/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.meta.service.table.impl;

import cn.hutool.core.io.IoUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.je.common.base.DynaBean;
import com.je.common.base.JsonBuilder;
import com.je.common.base.constants.ConstantVars;
import com.je.common.base.constants.table.ColumnType;
import com.je.common.base.constants.table.TableType;
import com.je.common.base.constants.tree.TreeNodeType;
import com.je.common.base.db.JEDatabase;
import com.je.common.base.exception.APIWarnException;
import com.je.common.base.exception.PlatformException;
import com.je.common.base.exception.PlatformExceptionEnum;
import com.je.common.base.service.CommonCheckService;
import com.je.common.base.service.CommonService;
import com.je.common.base.service.MetaService;
import com.je.common.base.service.rpc.BeanService;
import com.je.common.base.table.BuildingSqlFactory;
import com.je.common.base.util.*;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.meta.cache.table.DynaCache;
import com.je.meta.cache.table.TableCache;
import com.je.meta.rpc.develop.DevelopLogRpcService;
import com.je.meta.service.SystemColumnTypeEnum;
import com.je.meta.service.table.*;
import com.je.servicecomb.CommonRequestService;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.regex.Pattern;

/**
 * @program: jecloud-meta
 * @author: LIULJ
 * @create: 2021-09-18 11:21
 * @description: 资源表列服务实现
 */
@Service
public class MetaTableColumnServiceImpl implements MetaTableColumnService, CommonRequestService {

    @Autowired
    private MetaService metaService;
    @Autowired
    private TableCache tableCache;
    @Autowired
    private DynaCache dynaCache;
    @Autowired
    private CommonService commonService;
    @Autowired
    private MetaTableService metaTableService;
    @Autowired
    private MetaTableTraceService metaTableTraceService;
    @Autowired
    private MetaTableKeyService metaTableKeyService;
    @Autowired
    private MetaTableIndexService metaTableIndexService;
    @Autowired
    private MetaTableColumnService metaTableColumnService;
    @Autowired
    private DevelopLogRpcService developLogRpcService;

    @Autowired
    private CommonCheckService commonCheckService;

    public Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    @Transactional
    public Integer removeColumn(DynaBean dynaBean, String ids) {
        return removeColumn(dynaBean, ids, false);
    }

    /**
     * 删除列
     *
     * @param dynaBean 自定义动态类
     * @param ids      列id
     * @param isDll    是否执行DDL
     * @return
     */
    @Override
    @Transactional
    public Integer removeColumn(DynaBean dynaBean, String ids, Boolean isDll) {
        String columnTablecode = dynaBean.getStr("TABLECOLUMN_TABLECODE");
        //table信息
        DynaBean table = metaService.selectOne("JE_CORE_RESOURCETABLE", ConditionsWrapper.builder().eq("RESOURCETABLE_TABLECODE", columnTablecode));
        //视图删除特殊处理
        if ("VIEW".equalsIgnoreCase(table.getStr("RESOURCETABLE_TYPE"))) {
            return metaService.executeSql("DELETE FROM JE_CORE_TABLECOLUMN WHERE JE_CORE_TABLECOLUMN_ID IN ({0})", Arrays.asList(ids.split(",")));
        }

        List<DynaBean> columns = metaService.select(ConditionsWrapper.builder().table("JE_CORE_TABLECOLUMN").in("JE_CORE_TABLECOLUMN_ID", ids.split(",")));
        deleteCascadeViewColumn(columnTablecode, columns);
        //级联删除key键
        List<DynaBean> keys = getDelKeys(columns);
        List<DynaBean> indexs = getDelIndexs(columns);

        metaTableKeyService.deleteKey(columnTablecode, keys, "1");
        metaTableIndexService.deleteIndex(columnTablecode, indexs);
        deleteColumn(columnTablecode, columns, isDll);
        tableCache.removeCache(columnTablecode);
        dynaCache.removeCache(columnTablecode);
        metaService.clearMyBatisTableCache(columnTablecode);
        List<DynaBean> funcinfoList = metaService.select("JE_CORE_FUNCINFO", ConditionsWrapper.builder().eq("FUNCINFO_TABLENAME", columnTablecode));
        for (DynaBean funcinfo : funcinfoList) {
            metaService.clearMyBatisFuncCache(funcinfo.getStr("FUNCINFO_FUNCCODE"));
        }
        return columns.size();
    }

    @Override
    public boolean checkIsExistForeignKeyByColumnIds(String ids) {
        List<DynaBean> columns = metaService.select(ConditionsWrapper.builder().table("JE_CORE_TABLECOLUMN").in("JE_CORE_TABLECOLUMN_ID", ids.split(",")));
        if(columns==null || columns.size()==0){
            return false;
        }
        String tableId = columns.get(0).getStr("TABLECOLUMN_RESOURCETABLE_ID");
        for(DynaBean column:columns){
            //是否在当前表参与构建外键
            String code = column.getStr("TABLECOLUMN_CODE");
            List<DynaBean> currentTableKey = metaService.select("JE_CORE_TABLEKEY",
                    ConditionsWrapper.builder().eq("TABLEKEY_COLUMNCODE",code)
                            .eq("TABLEKEY_RESOURCETABLE_ID",tableId).eq("TABLEKEY_TYPE","Foreign"));

            if(currentTableKey!=null&&currentTableKey.size()>0){
                return true;
            }
            //是否在其他表参数构建外键，不需要此校验，在主表里不能删除外键字段，
            /*String tableCode = column.getStr("TABLECOLUMN_TABLECODE");
            List<DynaBean> otherTablekey = metaService.select("JE_CORE_TABLEKEY",
                    ConditionsWrapper.builder().eq("TABLEKEY_LINKTABLE",tableCode)
                            .eq("TABLEKEY_LINECOLUMNCODE",code).eq("TABLEKEY_TYPE","Foreign"));
            if(otherTablekey!=null&&otherTablekey.size()>0){
                return true;
            }*/
        }
        return false;
    }

    /**
     * 级联删除字段获取要删除的键
     *
     * @param columns
     * @return
     */
    public List<DynaBean> getDelKeys(List<DynaBean> columns) {
        List<DynaBean> keys = new ArrayList<>();
        List<String> columnsList = new ArrayList<>();
        if (columns.size() == 0) {
            return keys;
        }
        for (DynaBean column : columns) {
            columnsList.add(column.getStr("TABLECOLUMN_CODE"));
        }

        List<DynaBean> keyList = metaService.select("JE_CORE_TABLEKEY",
                ConditionsWrapper.builder()
                        .eq("TABLEKEY_RESOURCETABLE_ID", columns.get(0).get("TABLECOLUMN_RESOURCETABLE_ID"))
                        .in("TABLEKEY_COLUMNCODE", columnsList));

        for (DynaBean key : keyList) {
            if (key != null) {
                keys.add(key);
            }
        }
        for (DynaBean key : keys) {
            metaTableTraceService.saveTableTrace("JE_CORE_TABLEKEY", key, new DynaBean(), "DELETE", key.getStr("TABLEKEY_RESOURCETABLE_ID"), key.getStr("TABLEKEY_ISCREATE"));
        }
        return keys;
    }

    /**
     * 级联删除字段获取要删除的索引
     *
     * @param columns
     * @return
     */
    public List<DynaBean> getDelIndexs(List<DynaBean> columns) {
        List<DynaBean> indexs = new ArrayList<>();
        List<String> indexList = new ArrayList<>();
        if (columns.size() == 0) {
            return indexs;
        }

        for (DynaBean column : columns) {
            indexList.add(column.getStr("TABLECOLUMN_CODE"));
//            List<DynaBean> columnIndexs = metaService.select(ConditionsWrapper.builder()
//                    .table("JE_CORE_TABLEINDEX")
//                    .eq("TABLEINDEX_RESOURCETABLE_ID", column.getStr("TABLECOLUMN_RESOURCETABLE_ID"))
//                    .eq("TABLEINDEX_FIELDCODE", column.getStr("TABLECOLUMN_CODE")));
//            indexs.addAll(columnIndexs);
        }
        String resourcetableId = columns.get(0).getStr("TABLECOLUMN_RESOURCETABLE_ID");
        indexs = metaService.select("JE_CORE_TABLEINDEX", ConditionsWrapper.builder()
                .eq("TABLEINDEX_RESOURCETABLE_ID", resourcetableId)
                .in("TABLEINDEX_FIELDCODE", indexList));
        ///indexs = metaService.selectSql("SELECT * FROM JE_CORE_TABLEINDEX WHERE TABLEINDEX_RESOURCETABLE_ID = {0} and TABLEINDEX_FIELDCODE in ({1})", resourcetableId, indexList);

        for (DynaBean index : indexs) {
            metaTableTraceService.saveTableTrace("JE_CORE_TABLEINDEX", index, null, "DELETE", index.getStr("TABLEINDEX_RESOURCETABLE_ID"), index.getStr("TABLEINDEX_ISCREATE"));
        }
        return indexs;
    }

    @Override
    @Transactional
    public void deleteCascadeViewColumn(String tableCode, List<DynaBean> columns) {
        List<DynaBean> cascadeBeans = metaService.select("JE_CORE_VIEWCASCADE", ConditionsWrapper.builder()
                .eq("VIEWCASCADE_YBBM", tableCode)
                .or()
                .eq("VIEWCASCADE_MBBBM", tableCode));
        if (cascadeBeans == null || cascadeBeans.isEmpty()) {
            return;
        }

        List<DynaBean> columnList = Lists.newArrayList();
        List<String> viewIdList = Lists.newArrayList();
        List<String> viewCodeList = Lists.newArrayList();
        cascadeBeans.forEach(eachCascadeBean -> {
            viewIdList.add(eachCascadeBean.getStr("JE_CORE_RESOURCETABLE_ID"));
        });

        if (viewIdList.isEmpty()) {
            return;
        }

        //查找所有视图
        List<DynaBean> viewList = metaService.select("JE_CORE_RESOURCETABLE", ConditionsWrapper.builder().in("JE_CORE_RESOURCETABLE_ID", viewIdList));
        viewList.forEach(eachViewBean -> {
            viewCodeList.add(eachViewBean.getStr("RESOURCETABLE_TABLECODE"));
        });

        List<DynaBean> viewColumns = metaService.select("JE_CORE_TABLECOLUMN", ConditionsWrapper.builder().in("TABLECOLUMN_RESOURCETABLE_ID", viewIdList));
        columnList.addAll(acquireEqualColumns(tableCode, columns, viewColumns));

        if (columnList.isEmpty()) {
            return;
        }

        List<String> columnIdList = Lists.newArrayList();
        List<String> columnCodeList = Lists.newArrayList();
        columnList.forEach(eachViewColumnBean -> {
            columnIdList.add(eachViewColumnBean.getStr("JE_CORE_TABLECOLUMN_ID"));
            columnCodeList.add(eachViewColumnBean.getStr("TABLECOLUMN_CODE"));
        });
        //删除视图的字段
        metaService.delete("JE_CORE_TABLECOLUMN", ConditionsWrapper.builder().in("JE_CORE_TABLECOLUMN_ID", columnIdList));

        //查找使用视图得功能
        List<DynaBean> viewFuncList = metaService.select("JE_CORE_FUNCINFO", ConditionsWrapper.builder().in("FUNCINFO_TABLENAME", viewCodeList));
        List<String> viewFuncIdList = Lists.newArrayList();
        viewFuncList.forEach(eachBean -> {
            viewFuncIdList.add(eachBean.getStr("JE_CORE_FUNCINFO_ID"));
        });
        //删除功能列表的字段
        metaService.delete("JE_CORE_RESOURCECOLUMN", ConditionsWrapper.builder().in("RESOURCECOLUMN_FUNCINFO_ID", viewFuncIdList).in("RESOURCECOLUMN_CODE", columnCodeList));
        //删除功能表单的字段
        metaService.delete("JE_CORE_RESOURCEFIELD", ConditionsWrapper.builder().in("RESOURCEFIELD_FUNCINFO_ID", viewFuncIdList).in("RESOURCEFIELD_CODE", columnCodeList));
    }

    /**
     * 添加列
     *
     * @param dynaBean
     * @return
     */
    @Override
    @Transactional
    public String addField(DynaBean dynaBean) {
        String tablecolumnType = dynaBean.getStr("TABLECOLUMN_TYPE");
        String tablecolumnLength = dynaBean.getStr("TABLECOLUMN_LENGTH");
        Long length = StringUtil.isEmpty(tablecolumnLength) || "0".equals(tablecolumnLength) ? 0L : Long.parseLong(tablecolumnLength);
        String result = cheakColumn(tablecolumnType, length, dynaBean.getStr("TABLECOLUMN_TABLECODE"), dynaBean.getStr("TABLECOLUMN_CODE"));
        if (StringUtil.isNotEmpty(result)) {
            return result;
        }
        if ("VARCHAR".equals(tablecolumnType)) {
            if ("".equals(tablecolumnLength) || "0".equals(tablecolumnLength)) {
                dynaBean.setStr("TABLECOLUMN_LENGTH", "100");
            }
        }
        this.addFieldToLogicTable(dynaBean);
        metaTableService.updateTable(dynaBean.getStr("TABLECOLUMN_RESOURCETABLE_ID"), true);
        return null;
    }

    private String cheakColumn(String tablecolumnType, Long tablecolumnLength, String tableCode, String columnCode) {
        Long count = metaService.countBySql(ConditionsWrapper.builder()
                .table("JE_CORE_TABLECOLUMN")
                .eq("TABLECOLUMN_CODE", columnCode)
                .eq("TABLECOLUMN_TABLECODE", tableCode));
        if (count > 0) {
            return MessageUtils.getMessage("table.column.code.repeat");
        }
        if ("VARCHAR".equals(tablecolumnType) && tablecolumnLength > 4000) {
            return MessageUtils.getMessage("table.column.varchar.length.tooBig");
        }

        if ("NUMBER".equals(tablecolumnType) && tablecolumnLength > 255) {
            return MessageUtils.getMessage("table.column.number.length.tooBig");
        }
        if ("FLOAT".equals(tablecolumnType) && tablecolumnLength > 20) {
            return MessageUtils.getMessage("table.column.float.length.tooBig");
        }
        if (columnCode.matches("^-?[0-9]+")) {
            return MessageUtils.getMessage("column.canNott.all.be.numbers");
        }
        return null;

    }

    @Override
    public Map<String, Object> addFieldToLogicTable(DynaBean dynaBean) {
        Map<String, Object> map = new HashMap<>();
        String tablecolumnLength = dynaBean.getStr("TABLECOLUMN_LENGTH");
        Long length = StringUtil.isEmpty(tablecolumnLength) || "0".equals(tablecolumnLength) ? 0L : Long.parseLong(tablecolumnLength);
        String result = cheakColumn(dynaBean.getStr("TABLECOLUMN_TYPE"), length, dynaBean.getStr("TABLECOLUMN_TABLECODE"), dynaBean.getStr("TABLECOLUMN_CODE"));
        if (StringUtil.isNotEmpty(result)) {
            map.put("result", result);
            return map;
        }
        String tableCode = dynaBean.getTableCode();
        if (StringUtil.isEmpty(tableCode)) {
            dynaBean.set(BeanService.KEY_TABLE_CODE, "JE_CORE_TABLECOLUMN");
        }
        List<Map<String, Object>> listdb = metaService.selectSql("SELECT JE_CORE_RESOURCETABLE_ID from je_core_resourcetable WHERE RESOURCETABLE_TABLECODE=(select FUNCINFO_TABLENAME from je_core_funcinfo WHERE je_core_funcinfo_id={0})", dynaBean.getStr("funcinfoId"));
        if (listdb != null && listdb.size() > 0) {
            dynaBean.set("TABLECOLUMN_RESOURCETABLE_ID", listdb.get(0).get("JE_CORE_RESOURCETABLE_ID"));
        }
        map.put("resourcetableId", listdb.get(0).get("JE_CORE_RESOURCETABLE_ID"));
        commonService.buildModelCreateInfo(dynaBean);
        int count = 1;
        List<Map<String, Object>> countInfos = metaService.selectSql("SELECT MAX(SY_ORDERINDEX) ORDERINDEX FROM JE_CORE_TABLECOLUMN WHERE TABLECOLUMN_CLASSIFY='PRO' AND TABLECOLUMN_RESOURCETABLE_ID={0}", dynaBean.getStr("TABLECOLUMN_RESOURCETABLE_ID"));
        if (countInfos != null && countInfos.size() > 0 && countInfos.get(0) != null) {
            String countStr = countInfos.get(0).get("ORDERINDEX") + "";
            if (StringUtil.isNotEmpty(countStr)) {
                count = Integer.parseInt(countStr) + 1;
            }
        }
        //树型类型
        dynaBean.setStr("TABLECOLUMN_TREETYPE", "NORMAL");
        //是否为空
        dynaBean.setStr("TABLECOLUMN_ISNULL", "1");
        //是否创建
        dynaBean.setStr("TABLECOLUMN_ISCREATE", "1");
        dynaBean.set("SY_ORDERINDEX", count);
        dynaBean.set("TABLECOLUMN_CLASSIFY", "PRO");
        commonService.doSave(dynaBean);
        return map;
    }

    /**
     * 增量导入
     *
     * @param dynaBean
     */
    @Override
    @Transactional
    public void impNewCols(DynaBean dynaBean) {
        List<DynaBean> tableCols = metaService.select("JE_CORE_TABLECOLUMN",
                ConditionsWrapper.builder()
                        .eq("TABLECOLUMN_RESOURCETABLE_ID", dynaBean.getStr("JE_CORE_RESOURCETABLE_ID")));
        DynaBean currentTable = DataBaseUtils.getTableBaseInfo(dynaBean);
        //当前表中真实存在的列
        List<DynaBean> currentCols = (List<DynaBean>) currentTable.get(BeanService.KEY_TABLE_COLUMNS);
        //列表中显示的列
        for (int x = 0; x < currentCols.size(); x++) {
            DynaBean entity = currentCols.get(x);
            boolean flag = true;
            for (int i = 0; i < tableCols.size(); i++) {
                if (entity.getStr("TABLECOLUMN_CODE").equals(tableCols.get(i).getStr("TABLECOLUMN_CODE"))) {
                    flag = false;
                    break;
                }

            }
            if (flag) {
                commonService.doSave(dynaBean);
                metaService.insert(entity);
            }
        }
    }

    /**
     * 字典辅助添加列
     *
     * @param dynaBean
     */
    @Override
    @Transactional
    public String addColumnByDD(DynaBean dynaBean) {
        String ids = dynaBean.getStr("addColumnCodes");
        String ddCode = dynaBean.getStr("ddCode");
        DynaBean table = metaService.selectOne("JE_CORE_DICTIONARY", ConditionsWrapper.builder().eq("DICTIONARY_DDCODE", ddCode)
                .apply("and (SY_STATUS = '' or SY_STATUS = '1')"));
        String pkValue = dynaBean.getStr("JE_CORE_RESOURCETABLE_ID");
        String result = checkUnique(ids, pkValue);
        if (StringUtil.isNotEmpty(result)) {
            return MessageUtils.getMessage("column.exitsParam", result);
        }
        String ddName = dynaBean.getStr("ddName");
        String ddType = "";
        if (table != null) {
            ddType = table.getStr("DICTIONARY_DDTYPE");
        }
        int count = 1;
        List<Map<String, Object>> countInfos = metaService.selectSql("SELECT MAX(SY_ORDERINDEX) ORDERINDEX FROM JE_CORE_TABLECOLUMN WHERE TABLECOLUMN_CLASSIFY='PRO' AND TABLECOLUMN_RESOURCETABLE_ID={0}", pkValue);
        if (countInfos != null && countInfos.size() > 0 && countInfos.get(0) != null) {
            String countStr = countInfos.get(0).get("ORDERINDEX") + "";
            if (StringUtil.isNotEmpty(countStr)) {
                count = Integer.parseInt(countStr) + 1;
            }
        }
        String[] codeArray = ids.split(ArrayUtils.SPLIT);
        String queryField = "";
        Boolean idField = false;
        for (String code : codeArray) {
            if ("CODE".equalsIgnoreCase(code.substring(code.lastIndexOf("_") + 1))) {
                queryField = code;
            }
        }
        if (StringUtil.isEmpty(queryField)) {
            for (String code : codeArray) {
                if ("ID".equalsIgnoreCase(code.substring(code.lastIndexOf("_") + 1))) {
                    queryField = code;
                    idField = true;
                }
            }
        }
        String[] configInfoArray = new String[codeArray.length];
        for (int i = 0; i < codeArray.length; i++) {
            String code = codeArray[i];
            String type = code.substring(code.lastIndexOf("_") + 1);
            if ("name".equalsIgnoreCase(type)) {
                configInfoArray[i] = "text";
            } else if ("code".equalsIgnoreCase(type)) {
                configInfoArray[i] = "code";
            } else if ("id".equalsIgnoreCase(type)) {
                configInfoArray[i] = "id";
            }
        }
        for (String code : codeArray) {
            DynaBean column = new DynaBean("JE_CORE_TABLECOLUMN", false);
            column.set(BeanService.KEY_PK_CODE, "JE_CORE_TABLECOLUMN_ID");
            column.set("TABLECOLUMN_CODE", code);
            String type = code.substring(code.lastIndexOf("_") + 1);

            if (ArrayUtils.contains(new String[]{"DYNA_TREE", "SQL_TREE", "TREE"}, ddType)) {
                if ("name".equalsIgnoreCase(type)) {
                    column.set("TABLECOLUMN_NAME", ddName);
                } else if ("code".equalsIgnoreCase(type)) {
                    column.set("TABLECOLUMN_NAME", ddName + "_CODE");
                } else if ("id".equalsIgnoreCase(type)) {
                    column.set("TABLECOLUMN_NAME", ddName + "_ID");
                }
            } else if("JE_RBAC_DEPTTREE".equals(ddCode)){
                if ("name".equalsIgnoreCase(type)) {
                    column.set("TABLECOLUMN_NAME", ddName);
                } else if ("code".equalsIgnoreCase(type)) {
                    column.set("TABLECOLUMN_NAME", ddName + "_CODE");
                } else if ("id".equalsIgnoreCase(type)) {
                    column.set("TABLECOLUMN_NAME", ddName + "_ID");
                }
            } else {
                if ("name".equalsIgnoreCase(type)) {
                    column.set("TABLECOLUMN_NAME", ddName + "_NAME");
                } else if ("code".equalsIgnoreCase(type)) {
                    column.set("TABLECOLUMN_NAME", ddName);
                } else if ("id".equalsIgnoreCase(type)) {
                    column.set("TABLECOLUMN_NAME", ddName + "_ID");
                }
            }
            column.set("TABLECOLUMN_TYPE", "VARCHAR30");
            if ("id".equalsIgnoreCase(type)) {
                column.set("TABLECOLUMN_TYPE", "VARCHAR50");
            }
            column.set("TABLECOLUMN_UNIQUE", "0");
            column.set("TABLECOLUMN_CLASSIFY", "PRO");
            column.set("TABLECOLUMN_ISCREATE", "0");
            column.set("TABLECOLUMN_ISNULL", "1");
            column.set("TABLECOLUMN_LENGTH", "");
            column.set("TABLECOLUMN_TREETYPE", "NORMAL");
            column.set("TABLECOLUMN_RESOURCETABLE_ID", pkValue);
            column.setStr("TABLECOLUMN_SOURCE", "dictionary");
            String configInfo = StringUtil.buildSplitString(configInfoArray, "~");
            //树形字典
            if (ArrayUtils.contains(new String[]{"DYNA_TREE", "SQL_TREE", "TREE", "SQL", "CUSTOM"}, ddType)) {
                if ("NAME".equalsIgnoreCase(code.substring(code.lastIndexOf("_") + 1))) {
                    column.set("TABLECOLUMN_DICCONFIG", ddCode + "," + ids.replace(",", "~") + "," + configInfo + ",S");
                    column.set("TABLECOLUMN_DICQUERYFIELD", queryField);
                }
            } else {
                if ("CODE".equalsIgnoreCase(code.substring(code.lastIndexOf("_") + 1))) {
                    column.set("TABLECOLUMN_DICCONFIG", ddCode + "," + ids.replace(",", "~") + "," + configInfo + ",S");
                }
            }
            commonService.buildModelCreateInfo(column);
            column.set("SY_ORDERINDEX", count);
            count++;
            metaService.insert(column);
        }
        return null;
    }

    /**
     * 字典辅助添加列
     *
     * @param dynaBean
     */
    @Override
    @Transactional
    public String addColumnByDDList(DynaBean dynaBean) {
        String strData = dynaBean.getStr("strData");
        String result = checkStrData(strData, "name", dynaBean.getStr("JE_CORE_RESOURCETABLE_ID"));
        if (StringUtil.isNotEmpty(result)) {
            return MessageUtils.getMessage("column.exitsParam", result);
        }
        String pkValue = dynaBean.getStr("JE_CORE_RESOURCETABLE_ID");
        String whereSql = dynaBean.getStr("whereSql");
        int count = 1;
        List<Map<String, Object>> countInfos = metaService.selectSql("SELECT MAX(SY_ORDERINDEX) ORDERINDEX FROM JE_CORE_TABLECOLUMN WHERE TABLECOLUMN_CLASSIFY='PRO' AND TABLECOLUMN_RESOURCETABLE_ID={0}", pkValue);
        if (countInfos != null && countInfos.size() > 0 && countInfos.get(0) != null) {
            String countStr = countInfos.get(0).get("ORDERINDEX") + "";
            if (StringUtil.isNotEmpty(countStr)) {
                count = Integer.parseInt(countStr) + 1;
            }
        }
        JSONArray fields = JSONArray.parseArray(strData);
        for (int i = 0; i < fields.size(); i++) {
            JSONObject field = fields.getJSONObject(i);
            String type = field.getString("type");
            String name = field.getString("text");
            String code = field.getString("name");
            String configInfo = field.getString("configInfo");
            String otherConfig = field.getString("otherConfig");
            JSONObject config = new JSONObject();
            config.put("other", otherConfig);
            config.put("where", whereSql);
            DynaBean column = new DynaBean("JE_CORE_TABLECOLUMN", true);
            column.set("TABLECOLUMN_NAME", name);
            column.set("TABLECOLUMN_CODE", code);
            column.set("TABLECOLUMN_TYPE", "VARCHAR30");
            column.set("TABLECOLUMN_UNIQUE", "0");
            column.set("TABLECOLUMN_CLASSIFY", "PRO");
            column.set("TABLECOLUMN_ISCREATE", "0");
            column.set("TABLECOLUMN_ISNULL", "1");
            column.set("TABLECOLUMN_LENGTH", "");
            column.set("TABLECOLUMN_TREETYPE", "NORMAL");
            column.set("TABLECOLUMN_RESOURCETABLE_ID", pkValue);
            column.set("TABLECOLUMN_DICCONFIG", configInfo);
            column.set("TABLECOLUMN_DICQUERYFIELD", config.toString());
            commonService.buildModelCreateInfo(column);
            column.set("SY_ORDERINDEX", count);
            count++;
            metaService.insert(column);
        }
        return null;
    }

    private String checkStrData(String strData, String codekey, String tableId) {
        JSONArray jsonArray = JSONArray.parseArray(strData);
        String codes = "";
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            codes += jsonObject.getString(codekey) + ",";
        }
        codes = codes.substring(0, codes.length() - 1);
        return checkUnique(codes, tableId);
    }

    /**
     * 表辅助添加列
     *
     * @param dynaBean
     * @return
     */
    @Override
    @Transactional
    public String addColumnByTable(DynaBean dynaBean) {
        String strData = dynaBean.getStr("strData");
        String pkValue = dynaBean.getStr("JE_CORE_RESOURCETABLE_ID");
        String result = checkStrData(strData, "TABLECOLUMN_NEWCODE", pkValue);
        String FUNCCODE = dynaBean.getStr("FUNCCODE");
        String queryStr = dynaBean.getStr("queryStr");
        if (StringUtil.isNotEmpty(result)) {
            return MessageUtils.getMessage("column.exitsParam", result);
        }
        DynaBean oldBean = metaService.selectOneByPk("JE_CORE_RESOURCETABLE", pkValue);
        String tableCode = oldBean.getStr("RESOURCETABLE_TABLECODE");
        List<Map> sqlMapList = JsonBuilder.getInstance().fromJsonArray(strData);
        String targerTableCode = dynaBean.getStr("fromTableId");
        String createChild = dynaBean.getStr("CREATECHILD");
        int count = 1;
        List<Map<String, Object>> countInfos = metaService.selectSql("SELECT MAX(SY_ORDERINDEX) ORDERINDEX FROM JE_CORE_TABLECOLUMN WHERE TABLECOLUMN_CLASSIFY='PRO' AND TABLECOLUMN_RESOURCETABLE_ID={0}", pkValue);
        if (countInfos != null && countInfos.size() > 0 && countInfos.get(0) != null) {
            String countStr = countInfos.get(0).get("ORDERINDEX") + "";
            if (StringUtil.isNotEmpty(countStr)) {
                count = Integer.parseInt(countStr) + 1;
            }
        }

        for (Map map : sqlMapList) {
            //插入表字段
            DynaBean column = new DynaBean("JE_CORE_TABLECOLUMN", false);
            column.set(BeanService.KEY_PK_CODE, "JE_CORE_TABLECOLUMN_ID");
            column.set("TABLECOLUMN_NAME", map.get("TABLECOLUMN_NAME"));
            column.set("TABLECOLUMN_CODE", map.get("TABLECOLUMN_NEWCODE").toString().toUpperCase());
            column.set("TABLECOLUMN_UNIQUE", "0");
            if ("ID".equals(map.get("TABLECOLUMN_TYPE") + "")) {
                column.set("TABLECOLUMN_TYPE", "VARCHAR");
                column.set("TABLECOLUMN_LENGTH", "50");
            } else {
                column.set("TABLECOLUMN_TYPE", map.get("TABLECOLUMN_TYPE"));
                column.set("TABLECOLUMN_LENGTH", map.get("TABLECOLUMN_LENGTH"));
            }
            column.set("TABLECOLUMN_ISCREATE", "0");
            column.set("TABLECOLUMN_ISNULL", "1");
            column.set("TABLECOLUMN_CLASSIFY", "PRO");
            column.set("TABLECOLUMN_TABLECODE", tableCode);
            column.set("TABLECOLUMN_RESOURCETABLE_ID", pkValue);
            column.set("TABLECOLUMN_TREETYPE", "NORMAL");
            column.setStr("TABLECOLUMN_SOURCE", "table");
            if (map.containsKey("TABLECOLUMN_DICCONFIG")) {
                String dicConfig = map.get("TABLECOLUMN_DICCONFIG") + "";
                if (StringUtil.isNotEmpty(dicConfig)) {
                    for (Map vals : sqlMapList) {
                        dicConfig = dicConfig.replace(vals.get("TABLECOLUMN_CODE") + "", vals.get("TABLECOLUMN_NEWCODE") + "");
                    }
                    column.setStr("TABLECOLUMN_DICCONFIG", dicConfig);
                }
            }
            if (map.containsKey("TABLECOLUMN_DICQUERYFIELD")) {
                String dicQueryConfig = map.get("TABLECOLUMN_DICQUERYFIELD") + "";
                if (StringUtil.isNotEmpty(dicQueryConfig)) {
                    for (Map vals : sqlMapList) {
                        dicQueryConfig = dicQueryConfig.replace(vals.get("TABLECOLUMN_CODE") + "", vals.get("TABLECOLUMN_NEWCODE") + "");
                    }
                    column.setStr("TABLECOLUMN_DICQUERYFIELD", dicQueryConfig);
                }
            }

            if ("1".equals(createChild)) {
                column.set("TABLECOLUMN_CHILDCONFIG", targerTableCode + "," + map.get("TABLECOLUMN_CODE"));
            }
            commonService.buildModelCreateInfo(column);
            if ("1".equals(map.get("TABLECOLUMN_ISNULL") + "")) {
                //查询选择配置
                if (StringUtil.isNotEmpty(FUNCCODE)) {
                    column.set("TABLECOLUMN_QUERYCONFIG", FUNCCODE + "," + queryStr);
                }
            }
            //使用外键
            String targetTablecolumnType = map.get("TABLECOLUMN_TYPE")+"";
            if ("1".equals(createChild) && "ID".equals(map.get("TABLECOLUMN_TYPE") + "")) {
                column.set("TABLECOLUMN_TYPE", "CUSTOMFOREIGNKEY");
                if(ColumnType.CUSTOMID.equals(targetTablecolumnType)){
                    column.set("TABLECOLUMN_LENGTH", map.get("TABLECOLUMN_LENGTH")+"");
                }
                if(ColumnType.ID.equals(targetTablecolumnType)){
                    column.set("TABLECOLUMN_LENGTH", "VARCHAR(50)");
                }
                //生成外键
                DynaBean forenignKey = new DynaBean("JE_CORE_TABLEKEY", false);
                forenignKey.set(BeanService.KEY_PK_CODE, "JE_CORE_TABLEKEY_ID");
                String nowDateTime = DateUtils.formatDateTime(new Date());
                nowDateTime = nowDateTime.replaceAll("-", "");
                nowDateTime = nowDateTime.replaceAll(" ", "");
                nowDateTime = nowDateTime.replaceAll(":", "");
                forenignKey.set("TABLEKEY_CODE", "JE_" + nowDateTime);
                forenignKey.set("TABLEKEY_COLUMNCODE", column.get("TABLECOLUMN_CODE"));
                forenignKey.set("TABLEKEY_TYPE", "Foreign");
                forenignKey.set("TABLEKEY_CHECKED", "1");
                forenignKey.set("TABLEKEY_LINKTABLE", map.get("TABLECOLUMN_TABLECODE"));
                forenignKey.set("TABLEKEY_LINECOLUMNCODE", map.get("TABLECOLUMN_OLDCODE"));
                forenignKey.set("TABLEKEY_LINETYLE", "Cascade");
                forenignKey.set("TABLEKEY_ISRESTRAINT", "1");
                forenignKey.set("TABLEKEY_RESOURCETABLE_ID", pkValue);
                forenignKey.set("TABLEKEY_TABLECODE", tableCode);
                forenignKey.set("TABLEKEY_ISCREATE", "0");
                forenignKey.set("TABLEKEY_CLASSIFY", "PRO");
                forenignKey.set("SY_ORDERINDEX", 1);
                commonService.buildModelCreateInfo(forenignKey);
                metaService.insert(forenignKey);
            }
            column.set("SY_ORDERINDEX", count);
            count++;
            metaService.insert(column);
        }
        return null;
    }

    /**
     * 原子辅助添加列
     *
     * @param strData   数据主体
     * @param tableCode 表编码
     * @param pkValue   主键
     * @return
     */
    @Override
    @Transactional
    public Integer addColumnByAtom(String strData, String tableCode, String pkValue) {
        List<Map> sqlMapList = JsonBuilder.getInstance().fromJsonArray(strData);
        int count = 1;
        List<Map<String, Object>> countInfos = metaService.selectSql("SELECT MAX(SY_ORDERINDEX) ORDERINDEX FROM JE_CORE_TABLECOLUMN WHERE TABLECOLUMN_CLASSIFY='PRO' AND TABLECOLUMN_RESOURCETABLE_ID={0}", pkValue);
        if (countInfos != null && countInfos.size() > 0 && countInfos.get(0) != null) {
            String countStr = countInfos.get(0).get("ORDERINDEX") + "";
            if (StringUtil.isNotEmpty(countStr)) {
                count = Integer.parseInt(countStr) + 1;
            }
        }
        for (Map map : sqlMapList) {
            //插入表字段
            DynaBean column = new DynaBean("JE_CORE_TABLECOLUMN", false);
            column.set(BeanService.KEY_PK_CODE, "JE_CORE_TABLECOLUMN_ID");
            column.set("TABLECOLUMN_NAME", map.get("ATOMCOLUMN_NAME"));
            column.set("TABLECOLUMN_CODE", map.get("ATOMCOLUMN_CONTEXT"));
            column.set("TABLECOLUMN_UNIQUE", "0");
            column.set("TABLECOLUMN_TYPE", map.get("ATOMCOLUMN_TYPE"));
            column.set("TABLECOLUMN_LENGTH", map.get("ATOMCOLUMN_LENGTH"));
            column.set("TABLECOLUMN_ISCREATE", "0");
            column.set("TABLECOLUMN_ISNULL", "1");
            column.set("TABLECOLUMN_CLASSIFY", "PRO");
            column.set("TABLECOLUMN_TABLECODE", tableCode);
            column.set("TABLECOLUMN_RESOURCETABLE_ID", pkValue);
            column.set("TABLECOLUMN_TREETYPE", "NORMAL");
            column.set("SY_ORDERINDEX", count);
            count++;
            commonService.buildModelCreateInfo(column);
            metaService.insert(column);
        }
        return sqlMapList.size();
    }

    /**
     * 存为原子
     *
     * @param strData
     * @param pkValue 主键
     * @return
     */
    @Override
    @Transactional
    public Integer addAtomByColumn(String strData, String pkValue) {
        List<Map> sqlMapList = JsonBuilder.getInstance().fromJsonArray(strData);
        for (Map map : sqlMapList) {
            DynaBean atomColumn = new DynaBean("JE_CORE_ATOMCOLUMN", false);
            atomColumn.set(BeanService.KEY_TABLE_CODE, "JE_CORE_ATOMCOLUMN");
            atomColumn.set("ATOMCOLUMN_CODE", map.get("ATOMCOLUMN_CONTEXT"));
            atomColumn.set("ATOMCOLUMN_ISNULL", map.get("ATOMCOLUMN_ISNULL"));
            atomColumn.set("ATOMCOLUMN_NAME", map.get("ATOMCOLUMN_NAME"));
            atomColumn.set("ATOMCOLUMN_ATOM_ID", pkValue);
            atomColumn.set("ATOMCOLUMN_LENGTH", map.get("ATOMCOLUMN_LENGTH"));
            atomColumn.set("ATOMCOLUMN_TYPE", map.get("ATOMCOLUMN_TYPE"));
            commonService.buildModelCreateInfo(atomColumn);
            metaService.insert(atomColumn);
        }
        return sqlMapList.size();
    }


    @Override
    @Transactional
    public void deleteColumnMeta(String tableCode, List<DynaBean> columns) {
        List<String> columnCodes = new ArrayList<String>();
        String[] delIds = new String[columns.size()];
        for (int i = 0; i < columns.size(); i++) {
            DynaBean tc = columns.get(i);
            columnCodes.add(tc.getStr("TABLECOLUMN_CODE"));
            delIds[i] = tc.getStr("JE_CORE_TABLECOLUMN_ID");
            metaTableTraceService.saveTableTrace("JE_CORE_TABLECOLUMN", columns.get(i), "DELETE",
                    columns.get(i).getStr("TABLECOLUMN_RESOURCETABLE_ID"), columns.get(i).getStr("TABLECOLUMN_ISCREATE"));
        }
        if (delIds.length > 0) {
            metaService.executeSql("DELETE FROM JE_CORE_TABLECOLUMN WHERE JE_CORE_TABLECOLUMN_ID IN ({0})", Arrays.asList(delIds));
        }
        tableCache.removeCache(tableCode);
        DynaBean tableinfo = metaService.selectOne("JE_CORE_RESOURCETABLE", ConditionsWrapper.builder().eq("RESOURCETABLE_TABLECODE", tableCode));
        if ("1".equals(tableinfo.getStr("RESOURCETABLE_ISCREATE"))) {
            List<DynaBean> funcs = metaService.select("JE_CORE_FUNCINFO", ConditionsWrapper.builder().eq("FUNCINFO_TABLENAME", tableCode));
            for (DynaBean funInfo : funcs) {
                List<DynaBean> funColumns = metaService.select("JE_CORE_RESOURCECOLUMN",
                        ConditionsWrapper.builder().eq("RESOURCECOLUMN_FUNCINFO_ID", funInfo.getStr("JE_CORE_FUNCINFO_ID")));

                List<DynaBean> funFields = metaService.select("JE_CORE_RESOURCEFIELD",
                        ConditionsWrapper.builder().eq("RESOURCEFIELD_FUNCINFO_ID", funInfo.getStr("JE_CORE_FUNCINFO_ID")));
                //删除功能列表字段
                Boolean flag = false;
                List<String> ids = new ArrayList<String>();
                for (DynaBean rc : funColumns) {
                    if (columnCodes.contains(rc.getStr("RESOURCECOLUMN_CODE"))) {
                        flag = true;
                        ids.add(rc.getStr("JE_CORE_RESOURCECOLUMN_ID"));
                    }
                }
                if (flag && !ids.isEmpty()) {
                    metaService.executeSql("DELETE FROM JE_CORE_RESOURCECOLUMN WHERE JE_CORE_RESOURCECOLUMN_ID IN ({0})", ids);
                }
                Boolean fieldFlag = false;
                List<String> fieldIds = new ArrayList<String>();
                //删除功能表单字段
                for (DynaBean rf : funFields) {
                    if (columnCodes.contains(rf.getStr("RESOURCEFIELD_CODE"))) {
                        fieldFlag = true;
                        fieldIds.add(rf.getStr("JE_CORE_RESOURCEFIELD_ID"));
                    }
                }
                if (fieldFlag && !fieldIds.isEmpty()) {
                    metaService.executeSql("DELETE FROM JE_CORE_RESOURCEFIELD WHERE JE_CORE_RESOURCEFIELD_ID IN ({0})", fieldIds);
                }

                //删除用户列表个性化字段
                Boolean ucFlag = false;
                List<String> ucIds = new ArrayList<String>();
                List<DynaBean> userColumns = metaService.select("JE_CORE_USERINFO_COLUMN",
                        ConditionsWrapper.builder().eq("COLUMN_FUNCID", funInfo.getStr("JE_CORE_FUNCINFO_ID")));
                for (DynaBean uc : userColumns) {
                    if (columnCodes.contains(uc.getStr("COLUMN_CODE"))) {
                        ucFlag = true;
                        ucIds.add(uc.getStr("JE_CORE_USERINFO_COLUMN_ID"));
                    }
                }
                if (ucFlag && !ucIds.isEmpty()) {
                    metaService.executeSql("DELETE FROM JE_CORE_USERINFO_COLUMN WHERE JE_CORE_USERINFO_COLUMN_ID IN ({0})", ucIds);
                }
            }
        }
    }

    @Override
    public List<String> requireDeletePhysicalColumnDDL(String tableCode, List<DynaBean> columns) {
        List<String> delSqls = BuildingSqlFactory.build().getDeleteColumnSql(tableCode, columns);
        return delSqls;
    }

    @Override
    @Transactional
    public void deleteColumn(String tableCode, List<DynaBean> columns, Boolean isDdl) {
        //删除表字段
        if (isDdl) {
            List<String> delSqls = BuildingSqlFactory.build().getDeleteColumnSql(tableCode, columns);
            for (String delSql : delSqls) {
                if (StringUtil.isNotEmpty(delSql)) {
                    metaService.executeSql(delSql);
                }
            }
        }
        deleteColumnMeta(tableCode, columns);
    }


    @Override
    @Transactional
    public void initColumns(DynaBean resourceTable, Boolean isTree) {
        String tableCode = resourceTable.getStr("RESOURCETABLE_TABLECODE");
        List<DynaBean> columns = new ArrayList<DynaBean>();

        /**登记者所在部门主键*/
        DynaBean createOrgId = new DynaBean("JE_CORE_TABLECOLUMN", false);
        buildColumn(createOrgId, "SY_CREATEORGID", "登记部门主键", 312);
        createOrgId.set("TABLECOLUMN_TYPE", "VARCHAR50");
        createOrgId.set("TABLECOLUMN_LENGTH", "");
        createOrgId.set("TABLECOLUMN_NAME_EN", "Dept ID");
        columns.add(createOrgId);
        /**登记者所在部门名称*/
        DynaBean createOrgName = new DynaBean("JE_CORE_TABLECOLUMN", false);
        buildColumn(createOrgName, "SY_CREATEORGNAME", "登记部门", 314);
        createOrgName.set("TABLECOLUMN_TYPE", "VARCHAR50");
        createOrgName.set("TABLECOLUMN_LENGTH", "");
        createOrgName.set("TABLECOLUMN_NAME_EN", "Dept");
        columns.add(createOrgName);
        /**登记时间*/
        DynaBean createTime = new DynaBean("JE_CORE_TABLECOLUMN", false);
        buildColumn(createTime, "SY_CREATETIME", "登记时间", 315);
        createTime.set("TABLECOLUMN_TYPE", "DATETIME");
        createTime.set("TABLECOLUMN_NAME_EN", "Create Time");
        columns.add(createTime);
        /**登记人主键*/
        DynaBean createUserId = new DynaBean("JE_CORE_TABLECOLUMN", false);
        buildColumn(createUserId, "SY_CREATEUSERID", "登记人主键", 316);
        createUserId.set("TABLECOLUMN_TYPE", "VARCHAR50");
        createUserId.set("TABLECOLUMN_LENGTH", "");
        createUserId.set("TABLECOLUMN_NAME_EN", "User ID");
        columns.add(createUserId);
        /**登记人姓名*/
        DynaBean createUserName = new DynaBean("JE_CORE_TABLECOLUMN", false);
        buildColumn(createUserName, "SY_CREATEUSERNAME", "登记人", 318);
        createUserName.set("TABLECOLUMN_TYPE", "VARCHAR50");
        createUserName.set("TABLECOLUMN_LENGTH", "");
        createUserName.set("TABLECOLUMN_NAME_EN", "User");
        columns.add(createUserName);
        /**数据状态*/
        DynaBean status = new DynaBean("JE_CORE_TABLECOLUMN", false);
        buildColumn(status, "SY_STATUS", "数据状态", 319);
        status.set("TABLECOLUMN_TYPE", "" + "YESORNO");
        status.set("TABLECOLUMN_NAME_EN", "Data Status");
        columns.add(status);
        /**排序字段*/
        DynaBean orderIndex = new DynaBean("JE_CORE_TABLECOLUMN", false);
        buildColumn(orderIndex, "SY_ORDERINDEX", "排序字段", 320);
        orderIndex.set("TABLECOLUMN_NAME_EN", "Sort Field");
        if (isTree) {
            orderIndex.set("TABLECOLUMN_TREETYPE", TreeNodeType.ORDERINDEX.toString());
        }
        columns.add(orderIndex);

        /**公司ID*/
        DynaBean companyId = new DynaBean("JE_CORE_TABLECOLUMN", false);
        buildColumn(companyId, "SY_COMPANY_ID", "所属公司ID", 332);
        companyId.set("TABLECOLUMN_NAME_EN", "Company Id");
        companyId.set("TABLECOLUMN_TYPE", "VARCHAR50");
        companyId.set("TABLECOLUMN_LENGTH", "");
        columns.add(companyId);

        /**公司名称*/
        DynaBean companyName = new DynaBean("JE_CORE_TABLECOLUMN", false);
        buildColumn(companyName, "SY_COMPANY_NAME", "所属公司名称", 333);
        companyName.set("TABLECOLUMN_NAME_EN", "Company Name");
        companyName.set("TABLECOLUMN_TYPE", "VARCHAR255");
        companyName.set("TABLECOLUMN_LENGTH", "");
        columns.add(companyName);

        /**集团公司ID*/
        DynaBean groupCompanyId = new DynaBean("JE_CORE_TABLECOLUMN", false);
        buildColumn(groupCompanyId, "SY_GROUP_COMPANY_ID", "所属集团公司ID", 334);
        groupCompanyId.set("TABLECOLUMN_NAME_EN", "Group Company Id");
        groupCompanyId.set("TABLECOLUMN_TYPE", "VARCHAR50");
        groupCompanyId.set("TABLECOLUMN_LENGTH", "");
        columns.add(groupCompanyId);

        /**集团公司名称*/
        DynaBean groupCompanyName = new DynaBean("JE_CORE_TABLECOLUMN", false);
        buildColumn(groupCompanyName, "SY_GROUP_COMPANY_NAME", "所属集团公司名称", 335);
        groupCompanyName.set("TABLECOLUMN_NAME_EN", "Group Company Name");
        groupCompanyName.set("TABLECOLUMN_TYPE", "VARCHAR255");
        groupCompanyName.set("TABLECOLUMN_LENGTH", "");
        columns.add(groupCompanyName);

        /**机构ID*/
        DynaBean orgId = new DynaBean("JE_CORE_TABLECOLUMN", false);
        buildColumn(orgId, "SY_ORG_ID", "所属机构ID", 336);
        orgId.set("TABLECOLUMN_NAME_EN", "Org Id");
        orgId.set("TABLECOLUMN_TYPE", "VARCHAR50");
        orgId.set("TABLECOLUMN_LENGTH", "");
        columns.add(orgId);

        /**租户ID*/
        DynaBean tenantId = new DynaBean("JE_CORE_TABLECOLUMN", false);
        buildColumn(tenantId, "SY_TENANT_ID", "租户ID", 337);
        tenantId.set("TABLECOLUMN_NAME_EN", "Tenant Id");
        tenantId.set("TABLECOLUMN_TYPE", "VARCHAR50");
        tenantId.set("TABLECOLUMN_LENGTH", "");
        columns.add(tenantId);

        /**租户名称*/
        DynaBean tenantName = new DynaBean("JE_CORE_TABLECOLUMN", false);
        buildColumn(tenantName, "SY_TENANT_NAME", "租户名称", 338);
        tenantName.set("TABLECOLUMN_NAME_EN", "Tenant Name");
        tenantName.set("TABLECOLUMN_TYPE", "VARCHAR255");
        tenantName.set("TABLECOLUMN_LENGTH", "");
        columns.add(tenantName);

        /**ID字段*/
        DynaBean id = new DynaBean("JE_CORE_TABLECOLUMN", false);
        id.set("SY_ORDERINDEX", 300);
        id.set("TABLECOLUMN_CODE", tableCode + "_ID");
        id.set("TABLECOLUMN_TYPE", "ID");
        id.set("TABLECOLUMN_NAME", "主键ID");
        id.set("TABLECOLUMN_ISNULL", "0");
        id.set("TABLECOLUMN_CLASSIFY", "SYS");
        id.set("TABLECOLUMN_UNIQUE", "1");
        id.set("TABLECOLUMN_NAME_EN", "Primary Key");
        if (isTree) {
            id.set("TABLECOLUMN_TREETYPE", TreeNodeType.ID.toString());
        } else {
            id.set("TABLECOLUMN_TREETYPE", "NORMAL");
        }
        columns.add(id);
        /**树形字段设置*/
        if (isTree) {
            String prefix = tableCode.substring(tableCode.lastIndexOf("_") + 1);
            //父节点
            DynaBean parent = new DynaBean("JE_CORE_TABLECOLUMN", false);
            parent.set("SY_ORDERINDEX", 301);
            parent.set("TABLECOLUMN_TREETYPE", TreeNodeType.PARENT.toString());
            parent.set("TABLECOLUMN_CODE", "SY_PARENT");
            parent.set("TABLECOLUMN_TYPE", "VARCHAR50");
            parent.set("TABLECOLUMN_NAME", "父节点ID");
            parent.set("TABLECOLUMN_LENGTH", "");
            parent.set("TABLECOLUMN_ISNULL", "1");
            parent.set("TABLECOLUMN_CLASSIFY", "SYS");
            parent.set("TABLECOLUMN_NAME_EN", "Parent Node ID");
            columns.add(parent);
            //节点类型， 根、叶子、普通  区分
            DynaBean leaf = new DynaBean("JE_CORE_TABLECOLUMN", false);
            leaf.set("SY_ORDERINDEX", 302);
            leaf.set("TABLECOLUMN_TREETYPE", TreeNodeType.NODETYPE.toString());
            leaf.set("TABLECOLUMN_CODE", "SY_NODETYPE");
            leaf.set("TABLECOLUMN_TYPE", "VARCHAR50");
            leaf.set("TABLECOLUMN_NAME", "节点类型");
            leaf.set("TABLECOLUMN_LENGTH", "");
            leaf.set("TABLECOLUMN_ISNULL", "1");
            leaf.set("TABLECOLUMN_CLASSIFY", "SYS");
            leaf.set("TABLECOLUMN_NAME_EN", "Node Type");
            columns.add(leaf);
            //节点名称
            DynaBean text = new DynaBean("JE_CORE_TABLECOLUMN", false);
            text.set("SY_ORDERINDEX", 1);
            text.set("TABLECOLUMN_TREETYPE", TreeNodeType.TEXT.toString());
            text.set("TABLECOLUMN_CODE", prefix + "_TEXT");
            text.set("TABLECOLUMN_TYPE", "VARCHAR255");
            text.set("TABLECOLUMN_NAME", "节点名称");
            text.set("TABLECOLUMN_ISNULL", "1");
            text.set("TABLECOLUMN_CLASSIFY", "PRO");
            columns.add(text);
            //节点编码
            DynaBean code = new DynaBean("JE_CORE_TABLECOLUMN", false);
            code.set("SY_ORDERINDEX", 2);
            code.set("TABLECOLUMN_TREETYPE", TreeNodeType.CODE.toString());
            code.set("TABLECOLUMN_CODE", prefix + "_CODE");
            code.set("TABLECOLUMN_TYPE", "VARCHAR255");
            code.set("TABLECOLUMN_NAME", "节点编码");
            code.set("TABLECOLUMN_ISNULL", "1");
            code.set("TABLECOLUMN_CLASSIFY", "PRO");
            columns.add(code);
            //层次
            DynaBean layer = new DynaBean("JE_CORE_TABLECOLUMN", false);
            layer.set("SY_ORDERINDEX", 306);
            layer.set("TABLECOLUMN_TREETYPE", TreeNodeType.LAYER.toString());
            layer.set("TABLECOLUMN_CODE", "SY_LAYER");
            layer.set("TABLECOLUMN_NAME", "层次");
            layer.set("TABLECOLUMN_TYPE", "NUMBER");
            layer.set("TABLECOLUMN_LENGTH", "");
            layer.set("TABLECOLUMN_ISNULL", "1");
            layer.set("TABLECOLUMN_CLASSIFY", "SYS");
            layer.set("TABLECOLUMN_NAME_EN", "Layer");
            columns.add(layer);
            //树形路径
            DynaBean path = new DynaBean("JE_CORE_TABLECOLUMN", false);
            path.set("SY_ORDERINDEX", 307);
            path.set("TABLECOLUMN_TREETYPE", TreeNodeType.NODEPATH.toString());
            path.set("TABLECOLUMN_CODE", "SY_PATH");
            path.set("TABLECOLUMN_TYPE", "VARCHAR1000");
            path.set("TABLECOLUMN_LENGTH", "");
            path.set("TABLECOLUMN_NAME", "树形路径");
            path.set("TABLECOLUMN_ISNULL", "1");
            path.set("TABLECOLUMN_CLASSIFY", "SYS");
            path.set("TABLECOLUMN_NAME_EN", "Tree Path");
            columns.add(path);
            //是否启用
            DynaBean disabled = new DynaBean("JE_CORE_TABLECOLUMN", false);
            disabled.set("SY_ORDERINDEX", 308);
            disabled.set("TABLECOLUMN_TREETYPE", TreeNodeType.DISABLED.toString());
            disabled.set("TABLECOLUMN_CODE", "SY_DISABLED");
            disabled.set("TABLECOLUMN_TYPE", "YESORNO");
            disabled.set("TABLECOLUMN_LENGTH", "");
            disabled.set("TABLECOLUMN_NAME", "是否启用");
            disabled.set("TABLECOLUMN_ISNULL", "1");
            disabled.set("TABLECOLUMN_CLASSIFY", "SYS");
            disabled.set("TABLECOLUMN_NAME_EN", "Enable");
            columns.add(disabled);
            //树形排序
            DynaBean treeOrderIndex = new DynaBean("JE_CORE_TABLECOLUMN", false);
            treeOrderIndex.set("SY_ORDERINDEX", 309);
            treeOrderIndex.set("TABLECOLUMN_TREETYPE", TreeNodeType.TREEORDERINDEX.toString());
            treeOrderIndex.set("TABLECOLUMN_CODE", "SY_TREEORDERINDEX");
            treeOrderIndex.set("TABLECOLUMN_TYPE", "VARCHAR");
            if (ConstantVars.STR_MYSQL.equals(JEDatabase.getCurrentDatabase()) || ConstantVars.STR_TIDB.equals(JEDatabase.getCurrentDatabase())) {
                treeOrderIndex.set("TABLECOLUMN_LENGTH", "383");
            } else {
                treeOrderIndex.set("TABLECOLUMN_LENGTH", "900");
            }
            treeOrderIndex.set("TABLECOLUMN_NAME", "树形排序字段");
            treeOrderIndex.set("TABLECOLUMN_ISNULL", "1");
            treeOrderIndex.set("TABLECOLUMN_CLASSIFY", "SYS");
            treeOrderIndex.set("TABLECOLUMN_NAME_EN", "Tree Sort Field");
            columns.add(treeOrderIndex);
        }

        String nowDate = DateUtils.formatDateTime(new Date());
        for (DynaBean column : columns) {
            column.set(BeanService.KEY_PK_CODE, "JE_CORE_TABLECOLUMN_ID");
            column.set("SY_CREATETIME", nowDate);
            column.set("SY_CREATEUSERID", SecurityUserHolder.getCurrentAccountRealUserId());
            column.set("SY_CREATEUSERNAME", SecurityUserHolder.getCurrentAccountRealUserName());
            column.set("SY_CREATEORGID", SecurityUserHolder.getCurrentAccountRealOrgId());
            column.set("SY_CREATEORGNAME", SecurityUserHolder.getCurrentAccountRealOrgName());
            column.set("TABLECOLUMN_ISCREATE", "0");
            column.set("TABLECOLUMN_TABLECODE", tableCode);
            if (!"1".equals(column.getStr("TABLECOLUMN_UNIQUE", ""))) {
                column.set("TABLECOLUMN_UNIQUE", "0");
            }
            column.set("TABLECOLUMN_RESOURCETABLE_ID", resourceTable.getStr("JE_CORE_RESOURCETABLE_ID"));
            metaService.insert(column);
        }
    }

    @Override
    @Transactional
    public String checkColumns(List<DynaBean> columns, Boolean jeCore) {
        String errors = "";
        Set<String> columnCodes = new HashSet<String>();
        Integer pkCount = 0;
        String tableCode = "";
        Integer lengthCount = 0;
        List<String> pkCodeList = new ArrayList<String>();
        for (DynaBean column : columns) {
            if (StringUtil.isNotEmpty(column.getStr("TABLECOLUMN_TABLECODE")) && StringUtil.isEmpty(tableCode)) {
                tableCode = column.getStr("TABLECOLUMN_TABLECODE");
            }
            String columnCode = column.getStr("TABLECOLUMN_CODE");
            String columnType = column.getStr("TABLECOLUMN_TYPE");

            if (StringUtil.isEmpty(columnCode)) {
                errors = MessageUtils.getMessage("table.column.canNotEmpty");
                break;
            }

            if (columnCode.length() > 40) {
                errors = MessageUtils.getMessage("table.column.code.length", column.getStr("TABLECOLUMN_CODE"));
                break;
            }

            if (columnCodes.contains(columnCode)) {
                errors = MessageUtils.getMessage("table.column.code.multi", column.getStr("TABLECOLUMN_CODE"));
                break;
            }

            if (ColumnType.ID.equals(columnType)) {
                pkCodeList.add(column.getStr("TABLECOLUMN_CODE"));
                pkCount++;
            }

            //计算行长度
            if (ColumnType.VARCHAR255.equals(columnType)) {
                lengthCount += 255;
            } else if (ColumnType.VARCHAR100.equals(columnType)) {
                lengthCount += 100;
            } else if (ColumnType.VARCHAR50.equals(columnType)) {
                lengthCount += 50;
            } else if (ColumnType.VARCHAR30.equals(columnType)) {
                lengthCount += 30;
            } else if (ColumnType.VARCHAR767.equals(columnType)) {
                lengthCount += 767;
            } else if (ColumnType.VARCHAR1000.equals(columnType)) {
                lengthCount += 1000;
            } else if (ColumnType.VARCHAR2000.equals(columnType)) {
                lengthCount += 2000;
            } else if (ColumnType.VARCHAR4000.equals(columnType)) {
                if (!((jeCore || ("SYS".equals(column.getStr("TABLECOLUMN_CLASSIFY"))))
                        && (ConstantVars.STR_MYSQL.equals(JEDatabase.getCurrentDatabase())
                        || ConstantVars.STR_TIDB.equals(JEDatabase.getCurrentDatabase())))) {
                    lengthCount += 4000;
                }
            } else if (ColumnType.VARCHAR.equals(columnType)) {
                if (StringUtil.isEmpty(column.getStr("TABLECOLUMN_LENGTH"))) {
                    errors = MessageUtils.getMessage("column.length.notEmpty", column.getStr("TABLECOLUMN_CODE"));
                    break;
                }
                if (StringUtil.isNotEmpty(column.getStr("TABLECOLUMN_LENGTH")) && StringUtil.isNumber(column.getStr("TABLECOLUMN_LENGTH"))) {
                    lengthCount += column.getInt(column.getStr("TABLECOLUMN_LENGTH"), 0);
                }
            }
            columnCodes.add(columnCode);
        }

        if (pkCount > 1) {
            MessageUtils.getMessage("table.column.id.multi", tableCode, StringUtil.buildSplitString(ArrayUtils.getArray(pkCodeList), ","));
        }

        if ((ConstantVars.STR_MYSQL.equals(JEDatabase.getCurrentDatabase())
                || ConstantVars.STR_TIDB.equals(JEDatabase.getCurrentDatabase()))
                && lengthCount >= 32766) {
            errors = MessageUtils.getMessage("table.column.totalLength ");
        }

        return errors;
    }

    private List<String> updateList = Arrays.asList(
            "SY_MODIFYORGID",
            "SY_MODIFYORGNAME",
            "SY_MODIFYUSERID",
            "SY_MODIFYUSERNAME",
            "SY_MODIFYTIME"
    );

    @Override
    @Transactional
    public boolean initUpdateColumns(DynaBean resourceTable) throws APIWarnException {
        int p = 0;
        List<String> works = updateList;
        List<String> tableList = new ArrayList<>();
        String tableCode = resourceTable.getStr("RESOURCETABLE_TABLECODE");
        List<Map<String, Object>> maps = metaService.selectSql("select TABLECOLUMN_CODE from JE_CORE_TABLECOLUMN where TABLECOLUMN_TABLECODE={0}", tableCode);
        Iterator<Map<String, Object>> it = maps.iterator();
        while (it.hasNext()) {
            Map<String, Object> data = (Map<String, Object>) it.next();
            String field = data.get("TABLECOLUMN_CODE").toString();
            tableList.add(field);
        }

        List<DynaBean> columns = new ArrayList<DynaBean>();
        if (!tableList.contains("SY_MODIFYORGID")) {
            /**修改人部门编码*/
            DynaBean modifyOrgId = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(modifyOrgId, "SY_MODIFYORGID", "修改人部门主键", 325);
            modifyOrgId.set("TABLECOLUMN_TYPE", "VARCHAR50");
            modifyOrgId.set("TABLECOLUMN_LENGTH", "");
            modifyOrgId.set("TABLECOLUMN_NAME_EN", "Modifier Dept ID");
            columns.add(modifyOrgId);
            p++;
        }

        if (!tableList.contains("SY_MODIFYORGNAME")) {
            /**修改人部门*/
            DynaBean modifyOrgName = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(modifyOrgName, "SY_MODIFYORGNAME", "修改人部门", 327);
            modifyOrgName.set("TABLECOLUMN_TYPE", "VARCHAR50");
            modifyOrgName.set("TABLECOLUMN_LENGTH", "");
            modifyOrgName.set("TABLECOLUMN_NAME_EN", "Modifier Dept");
            columns.add(modifyOrgName);
            p++;
        }

        if (!tableList.contains("SY_MODIFYUSERID")) {
            /**修改人主键*/
            DynaBean modifyUserId = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(modifyUserId, "SY_MODIFYUSERID", "修改人主键", 328);
            modifyUserId.set("TABLECOLUMN_TYPE", "VARCHAR50");
            modifyUserId.set("TABLECOLUMN_LENGTH", "");
            modifyUserId.set("TABLECOLUMN_NAME_EN", "Modifier User ID");
            columns.add(modifyUserId);
            p++;
        }

        if (!tableList.contains("SY_MODIFYUSERNAME")) {
            /**修改人*/
            DynaBean modifyUserName = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(modifyUserName, "SY_MODIFYUSERNAME", "修改人", 330);
            modifyUserName.set("TABLECOLUMN_TYPE", "VARCHAR50");
            modifyUserName.set("TABLECOLUMN_LENGTH", "");
            modifyUserName.set("TABLECOLUMN_NAME_EN", "Modifier User");
            columns.add(modifyUserName);
            p++;
        }

        if (!tableList.contains("SY_MODIFYTIME")) {
            /**修改时间*/
            DynaBean modifyTime = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(modifyTime, "SY_MODIFYTIME", "修改时间", 331);
            modifyTime.set("TABLECOLUMN_TYPE", "DATETIME");
            modifyTime.set("TABLECOLUMN_NAME_EN", "Modify Time");
            columns.add(modifyTime);
            p++;
        }
        if (0 == p) {
            throw new APIWarnException(MessageUtils.getMessage("table.generate.updateMulti"), "201", new Object[]{resourceTable});
        }

        String nowDate = DateUtils.formatDateTime(new Date());
        for (DynaBean column : columns) {
            column.set(BeanService.KEY_PK_CODE, "JE_CORE_TABLECOLUMN_ID");
            column.set("SY_CREATETIME", nowDate);
            column.set("SY_CREATEUSERID", SecurityUserHolder.getCurrentAccountRealUserId());
            column.set("SY_CREATEUSERNAME", SecurityUserHolder.getCurrentAccountRealUserName());
            column.set("SY_CREATEORGID", SecurityUserHolder.getCurrentAccountRealOrgId());
            column.set("SY_CREATEORGNAME", SecurityUserHolder.getCurrentAccountRealOrgName());
            column.set("TABLECOLUMN_ISCREATE", "0");
            column.set("TABLECOLUMN_TABLECODE", tableCode);
            if (!"1".equals(column.getStr("TABLECOLUMN_UNIQUE", ""))) {
                column.set("TABLECOLUMN_UNIQUE", "0");
            }
            column.set("TABLECOLUMN_RESOURCETABLE_ID", resourceTable.getStr("JE_CORE_RESOURCETABLE_ID"));
            metaService.insert(column);
        }
        return true;
    }

    private List<String> createList = Arrays.asList(
            "SY_CREATEORGID",
            "SY_CREATEORGNAME",
            "SY_CREATETIME",
            "SY_CREATEUSERID",
            "SY_CREATEUSERNAME"
    );

    @Override
    @Transactional
    public boolean initCreateColumns(DynaBean resourceTable) throws APIWarnException {
        int p = 0;
        List<String> works = createList;
        List<String> tableList = new ArrayList<>();
        String tableCode = resourceTable.getStr("RESOURCETABLE_TABLECODE");
        List<Map<String, Object>> maps = metaService.selectSql("select TABLECOLUMN_CODE from JE_CORE_TABLECOLUMN where TABLECOLUMN_TABLECODE={0}", tableCode);
        Iterator<Map<String, Object>> it = maps.iterator();
        while (it.hasNext()) {
            Map<String, Object> data = (Map<String, Object>) it.next();
            String field = data.get("TABLECOLUMN_CODE").toString();
            tableList.add(field);
        }
        Boolean isTree = false;
        if (TableType.TREETABLE.equals(resourceTable.getStr("RESOURCETABLE_TYPE"))) {
            isTree = true;
        }
        List<DynaBean> columns = new ArrayList<DynaBean>();
        if (!tableList.contains("SY_CREATEORGID")) {
            /**登记者所在部门主键*/
            DynaBean createOrgId = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(createOrgId, "SY_CREATEORGID", "登记部门主键", 312);
            createOrgId.set("TABLECOLUMN_TYPE", "VARCHAR50");
            createOrgId.set("TABLECOLUMN_LENGTH", "");
            createOrgId.set("TABLECOLUMN_NAME_EN", "Dept ID");
            columns.add(createOrgId);
            p++;
        }

        if (!tableList.contains("SY_CREATEORGNAME")) {
            /**登记者所在部门名称*/
            DynaBean createOrgName = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(createOrgName, "SY_CREATEORGNAME", "登记部门", 314);
            createOrgName.set("TABLECOLUMN_TYPE", "VARCHAR50");
            createOrgName.set("TABLECOLUMN_LENGTH", "");
            createOrgName.set("TABLECOLUMN_NAME_EN", "Dept");
            columns.add(createOrgName);
            p++;
        }

        if (!tableList.contains("SY_CREATETIME")) {
            /**登记时间*/
            DynaBean createTime = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(createTime, "SY_CREATETIME", "登记时间", 315);
            createTime.set("TABLECOLUMN_TYPE", "DATETIME");
            createTime.set("TABLECOLUMN_NAME_EN", "Create Time");
            columns.add(createTime);
            p++;
        }

        if (!tableList.contains("SY_CREATEUSERID")) {
            /**登记人主键*/
            DynaBean createUserId = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(createUserId, "SY_CREATEUSERID", "登记人主键", 316);
            createUserId.set("TABLECOLUMN_TYPE", "VARCHAR50");
            createUserId.set("TABLECOLUMN_LENGTH", "");
            createUserId.set("TABLECOLUMN_NAME_EN", "User ID");
            columns.add(createUserId);
            p++;
        }

        if (!tableList.contains("SY_CREATEUSERNAME")) {
            /**登记人姓名*/
            DynaBean createUserName = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(createUserName, "SY_CREATEUSERNAME", "登记人", 318);
            createUserName.set("TABLECOLUMN_TYPE", "VARCHAR50");
            createUserName.set("TABLECOLUMN_LENGTH", "");
            createUserName.set("TABLECOLUMN_NAME_EN", "User");
            columns.add(createUserName);
            p++;
        }

        if (!tableList.contains("SY_STATUS")) {
            /**数据状态*/
            DynaBean status = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(status, "SY_STATUS", "数据状态", 319);
            status.set("TABLECOLUMN_TYPE", "" + "YESORNO");
            status.set("TABLECOLUMN_NAME_EN", "Data Status");
            columns.add(status);
            p++;
        }

        if (!tableList.contains("SY_ORDERINDEX")) {
            /**排序字段*/
            DynaBean orderIndex = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(orderIndex, "SY_ORDERINDEX", "排序字段", 320);
            orderIndex.set("TABLECOLUMN_NAME_EN", "Sort Field");
            if (isTree) {
                orderIndex.set("TABLECOLUMN_TREETYPE", TreeNodeType.ORDERINDEX.toString());
            }
            columns.add(orderIndex);
            p++;
        }

        if (!tableList.contains("SY_COMPANY_ID")) {
            /**公司ID*/
            DynaBean companyId = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(companyId, "SY_COMPANY_ID", "所属公司ID", 332);
            companyId.set("TABLECOLUMN_NAME_EN", "Company Id");
            companyId.set("TABLECOLUMN_TYPE", "VARCHAR50");
            companyId.set("TABLECOLUMN_LENGTH", "");
            columns.add(companyId);
            p++;
        }

        if (!tableList.contains("SY_COMPANY_NAME")) {
            /**公司名称*/
            DynaBean companyName = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(companyName, "SY_COMPANY_NAME", "所属公司名称", 333);
            companyName.set("TABLECOLUMN_NAME_EN", "Company Name");
            companyName.set("TABLECOLUMN_TYPE", "VARCHAR255");
            companyName.set("TABLECOLUMN_LENGTH", "");
            columns.add(companyName);
            p++;
        }

        if (!tableList.contains("SY_GROUP_COMPANY_ID")) {
            /**集团公司ID*/
            DynaBean groupCompanyId = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(groupCompanyId, "SY_GROUP_COMPANY_ID", "所属集团公司ID", 334);
            groupCompanyId.set("TABLECOLUMN_NAME_EN", "Group Company Id");
            groupCompanyId.set("TABLECOLUMN_TYPE", "VARCHAR50");
            groupCompanyId.set("TABLECOLUMN_LENGTH", "");
            columns.add(groupCompanyId);
            p++;
        }

        if (!tableList.contains("SY_GROUP_COMPANY_NAME")) {
            /**集团公司名称*/
            DynaBean groupCompanyName = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(groupCompanyName, "SY_GROUP_COMPANY_NAME", "所属集团公司名称", 335);
            groupCompanyName.set("TABLECOLUMN_NAME_EN", "Group Company Name");
            groupCompanyName.set("TABLECOLUMN_TYPE", "VARCHAR255");
            groupCompanyName.set("TABLECOLUMN_LENGTH", "");
            columns.add(groupCompanyName);
            p++;
        }

        if (!tableList.contains("SY_ORG_ID")) {
            /**机构ID*/
            DynaBean orgId = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(orgId, "SY_ORG_ID", "所属机构ID", 336);
            orgId.set("TABLECOLUMN_NAME_EN", "Org Id");
            orgId.set("TABLECOLUMN_TYPE", "VARCHAR50");
            orgId.set("TABLECOLUMN_LENGTH", "");
            columns.add(orgId);
            p++;
        }

        if (!tableList.contains("SY_TENANT_ID")) {
            /**租户ID*/
            DynaBean tenantId = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(tenantId, "SY_TENANT_ID", "租户ID", 337);
            tenantId.set("TABLECOLUMN_NAME_EN", "Tenant Id");
            tenantId.set("TABLECOLUMN_TYPE", "VARCHAR50");
            tenantId.set("TABLECOLUMN_LENGTH", "");
            columns.add(tenantId);
            p++;
        }

        if (!tableList.contains("SY_TENANT_NAME")) {
            /**租户名称*/
            DynaBean tenantName = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(tenantName, "SY_TENANT_NAME", "租户名称", 338);
            tenantName.set("TABLECOLUMN_NAME_EN", "Tenant Name");
            tenantName.set("TABLECOLUMN_TYPE", "VARCHAR255");
            tenantName.set("TABLECOLUMN_LENGTH", "");
            columns.add(tenantName);
            p++;
        }

        /**树形字段设置*/
        if (isTree) {
            String prefix = tableCode.substring(tableCode.lastIndexOf("_") + 1);
            if (!tableList.contains("SY_PARENT")) {
                //父节点
                DynaBean parent = new DynaBean("JE_CORE_TABLECOLUMN", false);
                parent.set("SY_ORDERINDEX", 301);
                parent.set("TABLECOLUMN_TREETYPE", TreeNodeType.PARENT.toString());
                parent.set("TABLECOLUMN_CODE", "SY_PARENT");
                parent.set("TABLECOLUMN_TYPE", "VARCHAR50");
                parent.set("TABLECOLUMN_NAME", "父节点ID");
                parent.set("TABLECOLUMN_LENGTH", "");
                parent.set("TABLECOLUMN_ISNULL", "1");
                parent.set("TABLECOLUMN_CLASSIFY", "SYS");
                parent.set("TABLECOLUMN_NAME_EN", "Parent Node ID");
                columns.add(parent);
                p++;
            }
            if (!tableList.contains("SY_NODETYPE")) {
                //节点类型， 根、叶子、普通  区分
                DynaBean leaf = new DynaBean("JE_CORE_TABLECOLUMN", false);
                leaf.set("SY_ORDERINDEX", 302);
                leaf.set("TABLECOLUMN_TREETYPE", TreeNodeType.NODETYPE.toString());
                leaf.set("TABLECOLUMN_CODE", "SY_NODETYPE");
                leaf.set("TABLECOLUMN_TYPE", "VARCHAR50");
                leaf.set("TABLECOLUMN_NAME", "节点类型");
                leaf.set("TABLECOLUMN_LENGTH", "");
                leaf.set("TABLECOLUMN_ISNULL", "1");
                leaf.set("TABLECOLUMN_CLASSIFY", "SYS");
                leaf.set("TABLECOLUMN_NAME_EN", "Node Type");
                columns.add(leaf);
                p++;
            }
            if (!tableList.contains(prefix + "_TEXT")) {
                //节点名称
                DynaBean text = new DynaBean("JE_CORE_TABLECOLUMN", false);
                text.set("SY_ORDERINDEX", 1);
                text.set("TABLECOLUMN_TREETYPE", TreeNodeType.TEXT.toString());
                text.set("TABLECOLUMN_CODE", prefix + "_TEXT");
                text.set("TABLECOLUMN_TYPE", "VARCHAR255");
                text.set("TABLECOLUMN_NAME", "节点名称");
                text.set("TABLECOLUMN_ISNULL", "1");
                text.set("TABLECOLUMN_CLASSIFY", "PRO");
                columns.add(text);
                p++;
            }
            if (!tableList.contains(prefix + "_CODE")) {
                //节点编码
                DynaBean code = new DynaBean("JE_CORE_TABLECOLUMN", false);
                code.set("SY_ORDERINDEX", 2);
                code.set("TABLECOLUMN_TREETYPE", TreeNodeType.CODE.toString());
                code.set("TABLECOLUMN_CODE", prefix + "_CODE");
                code.set("TABLECOLUMN_TYPE", "VARCHAR255");
                code.set("TABLECOLUMN_NAME", "节点编码");
                code.set("TABLECOLUMN_ISNULL", "1");
                code.set("TABLECOLUMN_CLASSIFY", "PRO");
                columns.add(code);
                p++;
            }
            if (!tableList.contains("SY_LAYER")) {
                //层次
                DynaBean layer = new DynaBean("JE_CORE_TABLECOLUMN", false);
                layer.set("SY_ORDERINDEX", 306);
                layer.set("TABLECOLUMN_TREETYPE", TreeNodeType.LAYER.toString());
                layer.set("TABLECOLUMN_CODE", "SY_LAYER");
                layer.set("TABLECOLUMN_NAME", "层次");
                layer.set("TABLECOLUMN_TYPE", "NUMBER");
                layer.set("TABLECOLUMN_LENGTH", "");
                layer.set("TABLECOLUMN_ISNULL", "1");
                layer.set("TABLECOLUMN_CLASSIFY", "SYS");
                layer.set("TABLECOLUMN_NAME_EN", "Layer");
                columns.add(layer);
                p++;
            }
            if (!tableList.contains("SY_PATH")) {
                //树形路径
                DynaBean path = new DynaBean("JE_CORE_TABLECOLUMN", false);
                path.set("SY_ORDERINDEX", 307);
                path.set("TABLECOLUMN_TREETYPE", TreeNodeType.NODEPATH.toString());
                path.set("TABLECOLUMN_CODE", "SY_PATH");
                path.set("TABLECOLUMN_TYPE", "VARCHAR1000");
                path.set("TABLECOLUMN_LENGTH", "");
                path.set("TABLECOLUMN_NAME", "树形路径");
                path.set("TABLECOLUMN_ISNULL", "1");
                path.set("TABLECOLUMN_CLASSIFY", "SYS");
                path.set("TABLECOLUMN_NAME_EN", "Tree Path");
                columns.add(path);
                p++;
            }
            if (!tableList.contains("SY_DISABLED")) {
                //是否启用
                DynaBean disabled = new DynaBean("JE_CORE_TABLECOLUMN", false);
                disabled.set("SY_ORDERINDEX", 308);
                disabled.set("TABLECOLUMN_TREETYPE", TreeNodeType.DISABLED.toString());
                disabled.set("TABLECOLUMN_CODE", "SY_DISABLED");
                disabled.set("TABLECOLUMN_TYPE", "YESORNO");
                disabled.set("TABLECOLUMN_LENGTH", "");
                disabled.set("TABLECOLUMN_NAME", "是否启用");
                disabled.set("TABLECOLUMN_ISNULL", "1");
                disabled.set("TABLECOLUMN_CLASSIFY", "SYS");
                disabled.set("TABLECOLUMN_NAME_EN", "Enable");
                columns.add(disabled);
                p++;
            }
            if (!tableList.contains("SY_TREEORDERINDEX")) {
                //树形排序
                DynaBean treeOrderIndex = new DynaBean("JE_CORE_TABLECOLUMN", false);
                treeOrderIndex.set("SY_ORDERINDEX", 309);
                treeOrderIndex.set("TABLECOLUMN_TREETYPE", TreeNodeType.TREEORDERINDEX.toString());
                treeOrderIndex.set("TABLECOLUMN_CODE", "SY_TREEORDERINDEX");
                treeOrderIndex.set("TABLECOLUMN_TYPE", "VARCHAR");
                if (ConstantVars.STR_MYSQL.equals(JEDatabase.getCurrentDatabase()) || ConstantVars.STR_TIDB.equals(JEDatabase.getCurrentDatabase())) {
                    treeOrderIndex.set("TABLECOLUMN_LENGTH", "383");
                } else {
                    treeOrderIndex.set("TABLECOLUMN_LENGTH", "900");
                }
                treeOrderIndex.set("TABLECOLUMN_NAME", "树形排序字段");
                treeOrderIndex.set("TABLECOLUMN_ISNULL", "1");
                treeOrderIndex.set("TABLECOLUMN_CLASSIFY", "SYS");
                treeOrderIndex.set("TABLECOLUMN_NAME_EN", "Tree Sort Field");
                columns.add(treeOrderIndex);
                p++;
            }

        }

        if (0 == p) {
            throw new APIWarnException(MessageUtils.getMessage("table.generate.saveMulti"), "201", new Object[]{resourceTable});
        }

        String nowDate = DateUtils.formatDateTime(new Date());
        for (DynaBean column : columns) {
            column.set(BeanService.KEY_PK_CODE, "JE_CORE_TABLECOLUMN_ID");
            column.set("SY_CREATETIME", nowDate);
            column.set("SY_CREATEUSERID", SecurityUserHolder.getCurrentAccountRealUserId());
            column.set("SY_CREATEUSERNAME", SecurityUserHolder.getCurrentAccountRealUserName());
            column.set("SY_CREATEORGID", SecurityUserHolder.getCurrentAccountRealOrgId());
            column.set("SY_CREATEORGNAME", SecurityUserHolder.getCurrentAccountRealOrgName());
            column.set("TABLECOLUMN_ISCREATE", "0");
            column.set("TABLECOLUMN_TABLECODE", tableCode);
            if (!"1".equals(column.getStr("TABLECOLUMN_UNIQUE", ""))) {
                column.set("TABLECOLUMN_UNIQUE", "0");
            }
            column.set("TABLECOLUMN_RESOURCETABLE_ID", resourceTable.getStr("JE_CORE_RESOURCETABLE_ID"));
            metaService.insert(column);
        }
        return true;
    }

    @Override
    @Transactional
    public void initShColumns(DynaBean resourceTable) {
        String tableCode = resourceTable.getStr("RESOURCETABLE_TABLECODE");
        List<DynaBean> columns = new ArrayList<>();
        /**审核标识*/
        DynaBean shFlag = new DynaBean("JE_CORE_TABLECOLUMN", false);
        buildColumn(shFlag, "SY_ACKFLAG", "审核标识", 325);
        shFlag.set("TABLECOLUMN_TYPE", "YESORNO");
        shFlag.set("TABLECOLUMN_LENGTH", "");
        shFlag.set("TABLECOLUMN_NAME_EN", "");
        columns.add(shFlag);
        /**审核人*/
        DynaBean shUserName = new DynaBean("JE_CORE_TABLECOLUMN", false);
        buildColumn(shUserName, "SY_ACKUSERNAME", "审核人", 326);
        shUserName.set("TABLECOLUMN_TYPE", "VARCHAR255");
        shUserName.set("TABLECOLUMN_LENGTH", "");
        shUserName.set("TABLECOLUMN_NAME_EN", "");
        columns.add(shUserName);
        /**审核人ID*/
        DynaBean shUserId = new DynaBean("JE_CORE_TABLECOLUMN", false);
        buildColumn(shUserId, "SY_ACKUSERID", "审核人ID", 327);
        shUserId.set("TABLECOLUMN_TYPE", "VARCHAR255");
        shUserId.set("TABLECOLUMN_LENGTH", "");
        shUserId.set("TABLECOLUMN_NAME_EN", "");
        columns.add(shUserId);
        /**审核时间*/
        DynaBean shTime = new DynaBean("JE_CORE_TABLECOLUMN", false);
        buildColumn(shTime, "SY_ACKTIME", "审核时间", 328);
        shTime.set("TABLECOLUMN_TYPE", "DATETIME");
        shTime.set("TABLECOLUMN_LENGTH", "");
        shTime.set("TABLECOLUMN_NAME_EN", "");
        columns.add(shTime);

        String nowDate = DateUtils.formatDateTime(new Date());
        for (DynaBean column : columns) {
            column.set(BeanService.KEY_PK_CODE, "JE_CORE_TABLECOLUMN_ID");
            column.set("SY_CREATETIME", nowDate);
            column.set("SY_CREATEUSERID", SecurityUserHolder.getCurrentAccountRealUserId());
            column.set("SY_CREATEUSERNAME", SecurityUserHolder.getCurrentAccountRealUserName());
            column.set("SY_CREATEORGID", SecurityUserHolder.getCurrentAccountRealOrgId());
            column.set("SY_CREATEORGNAME", SecurityUserHolder.getCurrentAccountRealOrgName());
            column.set("TABLECOLUMN_ISCREATE", "0");
            column.set("TABLECOLUMN_TABLECODE", tableCode);
            if (!"1".equals(column.getStr("TABLECOLUMN_UNIQUE", ""))) {
                column.set("TABLECOLUMN_UNIQUE", "0");
            }
            column.set("TABLECOLUMN_RESOURCETABLE_ID", resourceTable.getStr("JE_CORE_RESOURCETABLE_ID"));
            metaService.insert(column);
        }
    }

    private List<String> workList = Arrays.asList(
            "SY_STARTEDUSER",
            "SY_STARTEDUSERNAME",
            "SY_APPROVEDUSERS",
            "SY_APPROVEDUSERNAMES",
            "SY_PREAPPROVUSERS",
            "SY_LASTFLOWINFO",
            "SY_PREAPPROVUSERNAMES",
            "SY_LASTFLOWUSER",
            "SY_LASTFLOWUSERID",
            "SY_WFWARN",
            "SY_WARNFLAG",
            "SY_CURRENTTASK"
    );

    @Override
    @Transactional
    public boolean initProcessExtendColumns(DynaBean resourceTable) throws APIWarnException {
        int p = 0;
        List<String> works = workList;
        List<String> tableList = new ArrayList<>();
        String tableCode = resourceTable.getStr("RESOURCETABLE_TABLECODE");
        List<Map<String, Object>> maps = metaService.selectSql("select TABLECOLUMN_CODE from JE_CORE_TABLECOLUMN where TABLECOLUMN_TABLECODE={0}", tableCode);
        Iterator<Map<String, Object>> it = maps.iterator();
        while (it.hasNext()) {
            Map<String, Object> data = (Map<String, Object>) it.next();
            String field = data.get("TABLECOLUMN_CODE").toString();
            tableList.add(field);
        }
        List<DynaBean> columns = new ArrayList<DynaBean>();
        if (!tableList.contains("SY_STARTEDUSER")) {
            /**流程启动人*/
            DynaBean startUser = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(startUser, "SY_STARTEDUSER", "流程启动人ID", 332);
            startUser.set("TABLECOLUMN_NAME_EN", "Starter ID");
            columns.add(startUser);
            p++;
        }

        if (!tableList.contains("SY_STARTEDUSERNAME")) {
            /**流程启动人*/
            DynaBean startUserName = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(startUserName, "SY_STARTEDUSERNAME", "流程启动人", 333);
            startUserName.set("TABLECOLUMN_NAME_EN", "Starter");
            columns.add(startUserName);
            p++;
        }

        if (!tableList.contains("SY_APPROVEDUSERS")) {
            /**流程已执行人*/
            DynaBean approvedUser = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(approvedUser, "SY_APPROVEDUSERS", "流程已执行人ID", 334);
            approvedUser.set("TABLECOLUMN_NAME_EN", "Executor ID");
            approvedUser.set("TABLECOLUMN_TYPE", "CLOB");
            approvedUser.set("TABLECOLUMN_LENGTH", "");
            columns.add(approvedUser);
            p++;
        }

        if (!tableList.contains("SY_APPROVEDUSERNAMES")) {
            /**流程已执行人*/
            DynaBean approvedUserName = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(approvedUserName, "SY_APPROVEDUSERNAMES", "流程已执行人", 335);
            approvedUserName.set("TABLECOLUMN_NAME_EN", "Executor");
            approvedUserName.set("TABLECOLUMN_TYPE", "CLOB");
            approvedUserName.set("TABLECOLUMN_LENGTH", "");
            columns.add(approvedUserName);
            p++;
        }

        if (!tableList.contains("SY_PREAPPROVUSERS")) {
            /**流程已执行人*/
            DynaBean preapprovUser = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(preapprovUser, "SY_PREAPPROVUSERS", "流程待执行人ID", 336);
            preapprovUser.set("TABLECOLUMN_NAME_EN", "Waiting ID");
            preapprovUser.set("TABLECOLUMN_TYPE", "VARCHAR");
            preapprovUser.set("TABLECOLUMN_LENGTH", "1000");
            columns.add(preapprovUser);
            p++;
        }

        if (!tableList.contains("SY_PREAPPROVUSERNAMES")) {
            /**流程已执行人*/
            DynaBean preapprovUserName = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(preapprovUserName, "SY_PREAPPROVUSERNAMES", "流程待执行人", 337);
            preapprovUserName.set("TABLECOLUMN_NAME_EN", "Waiting");
            preapprovUserName.set("TABLECOLUMN_TYPE", "VARCHAR");
            preapprovUserName.set("TABLECOLUMN_LENGTH", "1000");
            columns.add(preapprovUserName);
            p++;
        }

        if (!tableList.contains("SY_LASTFLOWUSER")) {
            /**流程任务指派人*/
            DynaBean lastFlowUser = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(lastFlowUser, "SY_LASTFLOWUSER", "流程任务指派人", 338);
            lastFlowUser.set("TABLECOLUMN_NAME_EN", "Waiting");
            lastFlowUser.set("TABLECOLUMN_TYPE", "VARCHAR");
            lastFlowUser.set("TABLECOLUMN_LENGTH", "1000");
            columns.add(lastFlowUser);
            p++;
        }

        if (!tableList.contains("SY_LASTFLOWUSERID")) {
            DynaBean lastFlowUserId = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(lastFlowUserId, "SY_LASTFLOWUSERID", "流程任务指派人ID", 338);
            lastFlowUserId.set("TABLECOLUMN_NAME_EN", "Waiting");
            lastFlowUserId.set("TABLECOLUMN_TYPE", "VARCHAR");
            lastFlowUserId.set("TABLECOLUMN_LENGTH", "1000");
            columns.add(lastFlowUserId);
            p++;
        }

        /*if (!tableList.contains("SY_WFWARN")) {
         *//**流程预警延期信息*//*
            DynaBean warnFlowUser = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(warnFlowUser, "SY_WFWARN", "流程预警延期信息", 339);
            warnFlowUser.set("TABLECOLUMN_NAME_EN", "Warning");
            warnFlowUser.set("TABLECOLUMN_TYPE", "CLOB");
            warnFlowUser.set("TABLECOLUMN_LENGTH", "");
            columns.add(warnFlowUser);
            p++;
        }*/

        /* if (!tableList.contains("SY_WARNFLAG")) {
         *//**流程预警延期标识*//*
            DynaBean warnFlag = new DynaBean("JE_CORE_TABLECOLUMN", false);
            //0正常，1预警，2延期
            buildColumn(warnFlag, "SY_WARNFLAG", "流程预警延期标识", 340);
            warnFlag.set("TABLECOLUMN_NAME_EN", "Warning Flag");
            warnFlag.set("TABLECOLUMN_TYPE", "YESORNO");
            warnFlag.set("TABLECOLUMN_LENGTH", "");
            columns.add(warnFlag);
            p++;
        }*/

        if (!tableList.contains("SY_CURRENTTASK")) {
            /**流程预警延期标识*/
            DynaBean currentTask = new DynaBean("JE_CORE_TABLECOLUMN", false);
            //0正常，1预警，2延期
            buildColumn(currentTask, "SY_CURRENTTASK", "当前执行节点", 340);
            currentTask.set("TABLECOLUMN_NAME_EN", "Warning Flag");
            currentTask.set("TABLECOLUMN_TYPE", "VARCHAR255");
            currentTask.set("TABLECOLUMN_LENGTH", "");
            columns.add(currentTask);
            p++;
        }

        /* if (!tableList.contains("SY_LASTFLOWINFO")) {
         *//**流程最后任务指派信息*//*
            DynaBean lastFlowInfo = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(lastFlowInfo, "SY_LASTFLOWINFO", "流程最后任务指派信息", 336);
            lastFlowInfo.set("TABLECOLUMN_NAME_EN", "Waiting ID");
            lastFlowInfo.set("TABLECOLUMN_TYPE", "VARCHAR");
            lastFlowInfo.set("TABLECOLUMN_LENGTH", "1000");
            columns.add(lastFlowInfo);
            p++;
        }*/
        if (p == 0) {
            throw new APIWarnException(MessageUtils.getMessage("table.generate.workMulti"), "201", new Object[]{resourceTable});
        }

        String nowDate = DateUtils.formatDateTime(new Date());
        for (DynaBean column : columns) {
            column.set(BeanService.KEY_PK_CODE, "JE_CORE_TABLECOLUMN_ID");
            column.set("SY_CREATETIME", nowDate);
            column.set("SY_CREATEUSERID", SecurityUserHolder.getCurrentAccountRealUserId());
            column.set("SY_CREATEUSERNAME", SecurityUserHolder.getCurrentAccountRealUserName());
            column.set("SY_CREATEORGID", SecurityUserHolder.getCurrentAccountRealOrgId());
            column.set("SY_CREATEORGNAME", SecurityUserHolder.getCurrentAccountRealOrgName());
            column.set("TABLECOLUMN_ISCREATE", "0");
            column.set("TABLECOLUMN_TABLECODE", tableCode);
            if (!"1".equals(column.getStr("TABLECOLUMN_UNIQUE", ""))) {
                column.set("TABLECOLUMN_UNIQUE", "0");
            }
            column.set("TABLECOLUMN_RESOURCETABLE_ID", resourceTable.getStr("JE_CORE_RESOURCETABLE_ID"));
            metaService.insert(column);
        }
        resourceTable.set("RESOURCETABLE_IMPLWF", "1");
        metaService.update(resourceTable);
        return true;
    }

    @Override
    @Transactional
    public void initSaasColumns(DynaBean resourceTable) {
        String tableCode = resourceTable.getStr("RESOURCETABLE_TABLECODE");
        List<DynaBean> columns = new ArrayList<DynaBean>();
        /**流程启动人*/
        DynaBean zhId = new DynaBean("JE_CORE_TABLECOLUMN", false);
        buildColumn(zhId, "SY_TENANT_ID", "租户ID", 23);
        zhId.set("TABLECOLUMN_NAME_EN", "SaasUser ID");
        zhId.set("TABLECOLUMN_TYPE", "VARCHAR50");
        zhId.set("TABLECOLUMN_LENGTH", "");
        zhId.set("TABLECOLUMN_NAME_EN", "SaasUser ID");
        columns.add(zhId);
        DynaBean zhMc = new DynaBean("JE_CORE_TABLECOLUMN", false);
        buildColumn(zhMc, "SY_ZHMC", "租户名称", 23);
        zhMc.set("TABLECOLUMN_NAME_EN", "SaasUser Name");
        zhMc.set("TABLECOLUMN_TYPE", "VARCHAR100");
        zhMc.set("TABLECOLUMN_LENGTH", "");
        columns.add(zhMc);
        String nowDate = DateUtils.formatDateTime(new Date());
        for (DynaBean column : columns) {
            column.set(BeanService.KEY_PK_CODE, "JE_CORE_TABLECOLUMN_ID");
            column.set("SY_CREATETIME", nowDate);
            column.set("SY_CREATEUSERID", SecurityUserHolder.getCurrentAccountRealUserId());
            column.set("SY_CREATEUSERNAME", SecurityUserHolder.getCurrentAccountRealUserName());
            column.set("SY_CREATEORGID", SecurityUserHolder.getCurrentAccountRealOrgId());
            column.set("SY_CREATEORGNAME", SecurityUserHolder.getCurrentAccountRealOrgName());
            column.set("TABLECOLUMN_ISCREATE", "0");
            column.set("TABLECOLUMN_TABLECODE", tableCode);
            if (!"1".equals(column.getStr("TABLECOLUMN_UNIQUE", ""))) {
                column.set("TABLECOLUMN_UNIQUE", "0");
            }
            column.set("TABLECOLUMN_RESOURCETABLE_ID", resourceTable.getStr("JE_CORE_RESOURCETABLE_ID"));
            metaService.insert(column);
        }
        developLogRpcService.doDevelopLog("INIT_SAAS_COLUMNS", "初始化SAAS基础字段", "TABLE", "资源表", resourceTable.getStr("RESOURCETABLE_TABLENAME"), resourceTable.getStr("RESOURCETABLE_TABLECODE"), resourceTable.getStr("JE_CORE_RESOURCETABLE_ID"), resourceTable.getStr("SY_PRODUCT_ID"));
    }


    @Override
    @Transactional
    public boolean initExtendColumns(DynaBean resourceTable) throws APIWarnException {
        String tableCode = resourceTable.getStr("RESOURCETABLE_TABLECODE");
        List<String> tableList = new ArrayList<>();
        List<Map<String, Object>> maps = metaService.selectSql("select TABLECOLUMN_CODE from JE_CORE_TABLECOLUMN where TABLECOLUMN_TABLECODE={0}", tableCode);
        Iterator<Map<String, Object>> it = maps.iterator();
        while (it.hasNext()) {
            Map<String, Object> data = (Map<String, Object>) it.next();
            String field = data.get("TABLECOLUMN_CODE").toString();
            tableList.add(field);
        }

        String nowDate = DateUtils.formatDateTime(new Date());
        //默十个自定义字段
        int p = 0;
        for (int i = 1, num = 10; i <= num; i++) {
            String rowNum = String.format("%02d", i);
            String code = "SY_EXTEND" + rowNum;
            if (tableList.contains(code)) {
                continue;
            }
            DynaBean column = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(column, code, "扩展字段" + rowNum, 200 + i);
            column.set("TABLECOLUMN_TYPE", "VARCHAR100");
            column.set("TABLECOLUMN_LENGTH", "");
            column.set(BeanService.KEY_PK_CODE, "JE_CORE_TABLECOLUMN_ID");
            column.set("SY_CREATETIME", nowDate);
            column.set("SY_CREATEUSERID", SecurityUserHolder.getCurrentAccountRealUserId());
            column.set("SY_CREATEUSERNAME", SecurityUserHolder.getCurrentAccountRealUserName());
            column.set("SY_CREATEORGID", SecurityUserHolder.getCurrentAccountRealOrgId());
            column.set("SY_CREATEORGNAME", SecurityUserHolder.getCurrentAccountRealOrgName());
            column.set("TABLECOLUMN_ISCREATE", "0");
            column.set("TABLECOLUMN_TABLECODE", tableCode);
            if (!"1".equals(column.getStr("TABLECOLUMN_UNIQUE", ""))) {
                column.set("TABLECOLUMN_UNIQUE", "0");
            }
            column.set("TABLECOLUMN_RESOURCETABLE_ID", resourceTable.getStr("JE_CORE_RESOURCETABLE_ID"));
            metaService.insert(column);
            p++;
        }
        if (p == 0) {
            throw new APIWarnException(MessageUtils.getMessage("table.generate.extendMulti"), "201", new Object[]{resourceTable});
        }
        //return BaseRespResult.successResult(MessageUtils.getMessage("table.generate.extendFiled"));
        developLogRpcService.doDevelopLog("INIT_EXTEND_COLUMNS", "初始化扩展字段", "TABLE", "资源表", resourceTable.getStr("RESOURCETABLE_TABLENAME"), resourceTable.getStr("RESOURCETABLE_TABLECODE"), resourceTable.getStr("JE_CORE_RESOURCETABLE_ID"), resourceTable.getStr("SY_PRODUCT_ID"));
        return true;
    }

    @Override
    public boolean initWfBaseColumns(DynaBean resourceTable) throws APIWarnException {
        int p = 0;
        String tableCode = resourceTable.getStr("RESOURCETABLE_TABLECODE");
        List<String> columsCode = new ArrayList<>();
        List<Map<String, Object>> maps = metaService.selectSql("select TABLECOLUMN_CODE from JE_CORE_TABLECOLUMN where TABLECOLUMN_TABLECODE={0}", tableCode);
        Iterator<Map<String, Object>> it = maps.iterator();
        while (it.hasNext()) {
            Map<String, Object> data = (Map<String, Object>) it.next();
            String field = data.get("TABLECOLUMN_CODE").toString();
            columsCode.add(field);
        }
        List<DynaBean> columns = new ArrayList();
        /**审核标记*/
        if (!columsCode.contains("SY_AUDFLAG")) {
            DynaBean audFlag = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(audFlag, "SY_AUDFLAG", "审核标记", 311);
            audFlag.set("TABLECOLUMN_TYPE", "VARCHAR");
            audFlag.set("TABLECOLUMN_LENGTH", "20");
            audFlag.set("TABLECOLUMN_NAME_EN", "Audit Flag");
            columns.add(audFlag);
            p++;
        }

        /**流程实例ID*/
        if (!columsCode.contains("SY_PIID")) {
            DynaBean piId = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(piId, "SY_PIID", "流程实例ID", 321);
            piId.set("TABLECOLUMN_NAME_EN", "Process Case ID");
            columns.add(piId);
            p++;
        }

        /**流程定义ID*/
        if (!columsCode.contains("SY_PDID")) {
            DynaBean pdId = new DynaBean("JE_CORE_TABLECOLUMN", false);
            buildColumn(pdId, "SY_PDID", "流程定义ID", 322);
            pdId.set("TABLECOLUMN_NAME_EN", "Process Definition ID");
            columns.add(pdId);
            p++;
        }
        if (p == 0) {
            throw new APIWarnException(MessageUtils.getMessage("table.generate.workMulti"), "201", new Object[]{resourceTable});
        }

        String nowDate = DateUtils.formatDateTime(new Date());
        for (DynaBean column : columns) {
            column.set(BeanService.KEY_PK_CODE, "JE_CORE_TABLECOLUMN_ID");
            column.set("SY_CREATETIME", nowDate);
            column.set("SY_CREATEUSER", SecurityUserHolder.getCurrentAccountRealUserId());
            column.set("SY_CREATEUSERNAME", SecurityUserHolder.getCurrentAccountRealUserName());
            column.set("SY_CREATEORG", SecurityUserHolder.getCurrentAccountRealOrgId());
            column.set("SY_CREATEORGNAME", SecurityUserHolder.getCurrentAccountRealOrgName());
            column.set("TABLECOLUMN_ISCREATE", "0");
            column.set("TABLECOLUMN_TABLECODE", tableCode);
            if (!"1".equals(column.getStr("TABLECOLUMN_UNIQUE", ""))) {
                column.set("TABLECOLUMN_UNIQUE", "0");
            }
            column.set("TABLECOLUMN_RESOURCETABLE_ID", resourceTable.getStr("JE_CORE_RESOURCETABLE_ID"));
            metaService.insert(column);
        }
        developLogRpcService.doDevelopLog("INIT_WFBASE_COLUMNS", "初始化流程基础字段", "TABLE", "资源表", resourceTable.getStr("RESOURCETABLE_TABLENAME"), resourceTable.getStr("RESOURCETABLE_TABLECODE"), resourceTable.getStr("JE_CORE_RESOURCETABLE_ID"), resourceTable.getStr("SY_PRODUCT_ID"));
        return true;
    }

    @Override
    public boolean initSecretColumns(DynaBean resourceTable) {
        String tableCode = resourceTable.getStr("RESOURCETABLE_TABLECODE");
        List<DynaBean> columns = new ArrayList<DynaBean>();
        /**密级编码*/
        DynaBean secretCode = new DynaBean("JE_CORE_TABLECOLUMN", false);
        buildColumn(secretCode, "SY_SECRET_CODE", "密级编码", 325);
        secretCode.set("TABLECOLUMN_TYPE", "VARCHAR30");
        secretCode.set("TABLECOLUMN_LENGTH", "");
        secretCode.set("TABLECOLUMN_NAME_EN", "Secret Code");
        columns.add(secretCode);
        /**密级名称*/
        DynaBean secretName = new DynaBean("JE_CORE_TABLECOLUMN", false);
        buildColumn(secretName, "SY_SECRET_NAME", "密级名称", 325);
        secretName.set("TABLECOLUMN_TYPE", "VARCHAR30");
        secretName.set("TABLECOLUMN_LENGTH", "");
        secretName.set("TABLECOLUMN_NAME_EN", "Secret Name");
        columns.add(secretName);

        String nowDate = DateUtils.formatDateTime(new Date());
        for (DynaBean column : columns) {
            column.set(BeanService.KEY_PK_CODE, "JE_CORE_TABLECOLUMN_ID");
            column.set("SY_CREATETIME", nowDate);
            column.set("SY_CREATEUSER", SecurityUserHolder.getCurrentAccountRealUserId());
            column.set("SY_CREATEUSERNAME", SecurityUserHolder.getCurrentAccountRealUserName());
            column.set("SY_CREATEORG", SecurityUserHolder.getCurrentAccountRealOrgId());
            column.set("SY_CREATEORGNAME", SecurityUserHolder.getCurrentAccountRealOrgName());
            column.set("TABLECOLUMN_ISCREATE", "0");
            column.set("TABLECOLUMN_TABLECODE", tableCode);
            if (!"1".equals(column.getStr("TABLECOLUMN_UNIQUE", ""))) {
                column.set("TABLECOLUMN_UNIQUE", "0");
            }
            column.set("TABLECOLUMN_RESOURCETABLE_ID", resourceTable.getStr("JE_CORE_RESOURCETABLE_ID"));
            metaService.insert(column);
        }
        developLogRpcService.doDevelopLog("INIT_PRODUCT_COLUMNS", "初始化密级字段", "TABLE", "资源表", resourceTable.getStr("RESOURCETABLE_TABLENAME"), resourceTable.getStr("RESOURCETABLE_TABLECODE"), resourceTable.getStr("JE_CORE_RESOURCETABLE_ID"), resourceTable.getStr("SY_PRODUCT_ID"));
        return true;
    }

    /**
     * 初始化产品字段
     *
     * @param table
     */
    @Override
    @Transactional
    public void initProductColumns(DynaBean table) {
        String tableCode = table.getStr("RESOURCETABLE_TABLECODE");
        List<DynaBean> columns = new ArrayList<DynaBean>();
        /**产品id*/
        DynaBean productId = new DynaBean("JE_CORE_TABLECOLUMN", false);
        buildColumn(productId, "SY_PRODUCT_ID", "产品ID", 325);
        productId.set("TABLECOLUMN_TYPE", "VARCHAR255");
        productId.set("TABLECOLUMN_LENGTH", "");
        productId.set("TABLECOLUMN_NAME_EN", "Product ID");
        columns.add(productId);
        /**产品编码*/
        DynaBean productCode = new DynaBean("JE_CORE_TABLECOLUMN", false);
        buildColumn(productCode, "SY_PRODUCT_CODE", "产品编码", 325);
        productCode.set("TABLECOLUMN_TYPE", "VARCHAR255");
        productCode.set("TABLECOLUMN_LENGTH", "");
        productCode.set("TABLECOLUMN_NAME_EN", "Product Code");
        columns.add(productCode);
        /**产品名称*/
        DynaBean productName = new DynaBean("JE_CORE_TABLECOLUMN", false);
        buildColumn(productName, "SY_PRODUCT_NAME", "产品名称", 325);
        productCode.set("TABLECOLUMN_TYPE", "VARCHAR255");
        productCode.set("TABLECOLUMN_LENGTH", "");
        productCode.set("TABLECOLUMN_NAME_EN", "Product Name");
        columns.add(productName);

        String nowDate = DateUtils.formatDateTime(new Date());
        for (DynaBean column : columns) {
            column.set(BeanService.KEY_PK_CODE, "JE_CORE_TABLECOLUMN_ID");
            column.set("SY_CREATETIME", nowDate);
            column.set("SY_CREATEUSER", SecurityUserHolder.getCurrentAccountRealUserId());
            column.set("SY_CREATEUSERNAME", SecurityUserHolder.getCurrentAccountRealUserName());
            column.set("SY_CREATEORG", SecurityUserHolder.getCurrentAccountRealOrgId());
            column.set("SY_CREATEORGNAME", SecurityUserHolder.getCurrentAccountRealOrgName());
            column.set("TABLECOLUMN_ISCREATE", "0");
            column.set("TABLECOLUMN_TABLECODE", tableCode);
            if (!"1".equals(column.getStr("TABLECOLUMN_UNIQUE", ""))) {
                column.set("TABLECOLUMN_UNIQUE", "0");
            }
            column.set("TABLECOLUMN_RESOURCETABLE_ID", table.getStr("JE_CORE_RESOURCETABLE_ID"));
            metaService.insert(column);
        }
        developLogRpcService.doDevelopLog("INIT_PRODUCT_COLUMNS", "初始化产品字段", "TABLE", "资源表", table.getStr("RESOURCETABLE_TABLENAME"), table.getStr("RESOURCETABLE_TABLECODE"), table.getStr("JE_CORE_RESOURCETABLE_ID"), table.getStr("SY_PRODUCT_ID"));
    }
    
    /**
     * 添加系统字段
     *
     * @param request
     */
    @Override
    public boolean addSystemColumn(HttpServletRequest request) throws APIWarnException {
        String type = getStringParameter(request, "type");
        if (SystemColumnTypeEnum.CREATE.getName().equals(type)) {
            return generateCreateInfo(request);
        } else if (SystemColumnTypeEnum.UPDATE.getName().equals(type)) {
            return generateUpdateInfo(request);
        } else if (SystemColumnTypeEnum.WORKFLOW_EXTEND.getName().equals(type)) {
            return initWfExtendColumn(request);
        } else if (SystemColumnTypeEnum.WORKFLOW_BASE.getName().equals(type)) {
            return initWfBaseColumn(request);
        } else if (SystemColumnTypeEnum.EXTEND.getName().equals(type)) {
            return initExtendColumn(request);
        } else if (SystemColumnTypeEnum.PRODUCT.getName().equals(type)) {
            return initProductColumn(request);
        }else if (SystemColumnTypeEnum.SECRET.getName().equals(type)) {
            return initSecretColumn(request);
        }
        return false;
    }

    /**
     * 表格键保存修改操作
     *
     * @param dynaBean
     * @param strData
     * @return
     */
    @Override
    public int doUpdateList(DynaBean dynaBean, String strData) {
        dynaBean.table("JE_CORE_TABLECOLUMN");
        String tableCode = dynaBean.getStr(BeanService.KEY_TABLE_CODE);
        String pkName = dynaBean.getStr(BeanService.KEY_PK_CODE);
        Map<String, DynaBean> oldMaps = new HashMap<String, DynaBean>();

        String[] ids = JsonUtil.jsonSqlToIdsStr(dynaBean, strData);
        List<Map> sqlMapList = JsonUtil.fromJsonArray(strData);
        String[] updateSqls = new String[sqlMapList.size()];
        for (int i = 0; i < sqlMapList.size(); i++) {
            Map sqlMap = sqlMapList.get(i);
            String sql = BuildingSqlFactory.build().getUpdateSql(tableCode, pkName, sqlMap);
            updateSqls[i] = sql;
            DynaBean oldBean = metaService.selectOneByPk("JE_CORE_TABLECOLUMN", sqlMap.get(pkName).toString());
            oldMaps.put(sqlMap.get(pkName) + "", oldBean);
        }
//				int rows = serviceTemplate.listUpdate(updateSqls);
        int rows = updateSqls.length;
        for (String sql : updateSqls) {
            metaService.executeSql(sql);
        }

        List<DynaBean> newBeans = metaService.select(ConditionsWrapper.builder()
                .table("JE_CORE_TABLECOLUMN")
                .in("JE_CORE_TABLECOLUMN_ID", ids));
        for (DynaBean bean : newBeans) {
            String pk = bean.getStr(pkName);
            DynaBean oldBean = oldMaps.get(pk);
            metaTableTraceService.saveTableTrace("JE_CORE_TABLECOLUMN", oldBean, bean, "UPDATE", oldBean.getStr("TABLECOLUMN_RESOURCETABLE_ID"), oldBean.getStr("TABLECOLUMN_ISCREATE"));
        }
        return rows;
    }

    /**
     * 字段列校验
     *
     * @param ids
     * @param pkValue
     * @return
     */
    @Override
    public String checkUnique(String ids, String pkValue) {
        String error = "";
        for (String code : ids.split(",")) {
            Long count = metaService.countBySql(ConditionsWrapper.builder()
                    .table("JE_CORE_TABLECOLUMN")
                    .eq("TABLECOLUMN_CODE", code)
                    .eq("TABLECOLUMN_RESOURCETABLE_ID", pkValue));
            if (count > 0) {
                error += code + ",";
            }
        }
        if (error.length() > 0) {
            error = error.substring(0, error.length() - 1);
        }
        return error;
    }

    /**
     * 保存更新列操作
     *
     * @param dynaBean
     * @param strData
     * @return
     */
    @Override
    public int doUpdateListByColumn(DynaBean dynaBean, String strData) throws APIWarnException {
        dynaBean.table("JE_CORE_TABLECOLUMN");
        String tableCode = dynaBean.getStr(BeanService.KEY_TABLE_CODE);
        String pkName = dynaBean.getStr(BeanService.KEY_PK_CODE);
        Map<String, DynaBean> oldMaps = new HashMap<String, DynaBean>();
        String[] ids = JsonUtil.jsonSqlToIdsStr(dynaBean, strData);
        List<Map> sqlMapList = JsonUtil.fromJsonArray(strData);
        String[] updateSqls = new String[sqlMapList.size()];
        for (int i = 0; i < sqlMapList.size(); i++) {
            Map sqlMap = sqlMapList.get(i);
            if ("CUSTOM".equals(sqlMap.get("TABLECOLUMN_TYPE"))) {
                Object tablecolumnLength = sqlMap.get("TABLECOLUMN_LENGTH");
                if (null == tablecolumnLength) {
                    throw new APIWarnException(MessageUtils.getMessage("table.column.type.formatEmpty"), "201", new Object[]{dynaBean});
                }
                if (StringUtil.isEmpty(tablecolumnLength.toString())) {
                    throw new APIWarnException(MessageUtils.getMessage("table.column.type.formatEmpty"), "201", new Object[]{dynaBean});
                }
                boolean matches = tablecolumnLength.toString().matches("^[^\\\\\\\\/*?:.\"\\'<>|\\x22]+$");
                if (!matches) {
                    throw new APIWarnException(MessageUtils.getMessage("table.column.type.formatWrong"), "201", new Object[]{dynaBean});
                }
            }
            String remark = sqlMap.get("TABLECOLUMN_REMARK")==null?"":sqlMap.get("TABLECOLUMN_REMARK").toString();
            if(StringUtil.isNotEmpty(remark)){
                //去掉所有空格
                remark=remark.replaceAll(" ","");
                sqlMap.put("TABLECOLUMN_REMARK",remark);
            }
            if (sqlMap.containsKey("_X_ROW_KEY")) {
                sqlMap.remove("_X_ROW_KEY");
            }
            logger.info("当前数据库=" + JEDatabase.getCurrentDatabase());
            logger.info("传入数据=" + sqlMap);
            String sql = BuildingSqlFactory.build().getUpdateSql(tableCode, pkName, sqlMap);
            updateSqls[i] = sql;
            DynaBean oldBean = metaService.selectOneByPk("JE_CORE_TABLECOLUMN", sqlMap.get(pkName).toString());
            //有外键不允许修改字段类型
            List<Map<String, Object>> keyList = metaService.selectSql("SELECT * FROM JE_CORE_TABLEKEY WHERE " +
                            "((TABLEKEY_LINKTABLE={0} AND TABLEKEY_LINECOLUMNCODE ={1})  " +
                            "OR (TABLEKEY_RESOURCETABLE_ID={2} AND TABLEKEY_COLUMNCODE={3}))" +
                            " AND TABLEKEY_TYPE!='Primary'", sqlMap.get("TABLECOLUMN_TABLECODE"), sqlMap.get("TABLECOLUMN_CODE"),
                    sqlMap.get("TABLECOLUMN_RESOURCETABLE_ID"), sqlMap.get("TABLECOLUMN_CODE"));
            if (keyList.size() > 0 && !oldBean.getStr("TABLECOLUMN_TYPE").equals(String.valueOf(sqlMap.get("TABLECOLUMN_TYPE")))) {
                throw new PlatformException(String.format(MessageUtils.getMessage("table.column.update.type"),
                        oldBean.getStr("TABLECOLUMN_NAME"), oldBean.getStr("TABLECOLUMN_TYPE"))
                        , PlatformExceptionEnum.UNKOWN_ERROR);
            }
            oldMaps.put(sqlMap.get(pkName) + "", oldBean);
        }
        int rows = updateSqls.length;
        for (String sql : updateSqls) {
            metaService.executeSql(sql);
        }

        List<DynaBean> newBeans = metaService.select(ConditionsWrapper.builder()
                .table("JE_CORE_TABLECOLUMN")
                .in("JE_CORE_TABLECOLUMN_ID", ids));
        for (DynaBean bean : newBeans) {
            String pk = bean.getStr(pkName);
            DynaBean oldBean = oldMaps.get(pk);
            metaTableTraceService.saveTableTrace("JE_CORE_TABLECOLUMN", oldBean, bean, "UPDATE", oldBean.getStr("TABLECOLUMN_RESOURCETABLE_ID"), oldBean.getStr("TABLECOLUMN_ISCREATE"));
        }
        return rows;
    }

    @Override
    public List<DynaBean> selectTableByPks(String tableCode, String[] resourcetableIds) {
        List<DynaBean> columns = metaService.select(ConditionsWrapper.builder().table(tableCode).in("JE_CORE_TABLECOLUMN_ID", resourcetableIds));
        return columns;
    }

    /**
     * 如果是ID不能删除列
     *
     * @param ids
     * @return
     */
    @Override
    public String checkTypeById(String ids) {
        String[] idArray = ids.split(ArrayUtils.SPLIT);
        List<DynaBean> columnsList = metaService.select("JE_CORE_TABLECOLUMN",
                ConditionsWrapper.builder()
                        .in("JE_CORE_TABLECOLUMN_ID", idArray));
        if (columnsList == null || columnsList.isEmpty()) {
            return null;
        }
        String tableId = columnsList.get(0).getStr("TABLECOLUMN_RESOURCETABLE_ID");
        for (DynaBean columns : columnsList) {
            /**
             * 校验是不是主键
             */
            if ("ID".equals(columns.getStr("TABLECOLUMN_TYPE"))) {
                return MessageUtils.getMessage("table.column.pkCode.conNotDel", columns.getStr("TABLECOLUMN_CODE"));
            }
            String result = checkColumnBelongtoView(tableId, columns.getStr("TABLECOLUMN_CODE"));
            if (StringUtil.isNotEmpty(result)) {
                return result;
            }
        }
        return null;
    }

    @Override
    public String checkStrData(String strData) {
        JSONArray data = JSONArray.parseArray(strData);
        String result = "";
        Set<String> codes = new HashSet<>();
        String RESOURCETABLE_IMPORT ="";
        String RESOURCETABLE_TYPE="";
        if(data!=null&&data.size()>0){
            JSONObject jsonObject =data.getJSONObject(0);
            String tableId =jsonObject.getString("TABLECOLUMN_RESOURCETABLE_ID");
            DynaBean table = metaService.selectOneByPk("JE_CORE_RESOURCETABLE",tableId);
            if(table!=null){
                RESOURCETABLE_IMPORT = table.getStr("RESOURCETABLE_IMPORT");
                RESOURCETABLE_TYPE = table.getStr("RESOURCETABLE_TYPE");
            }
        }
        for (int i = 0; i < data.size(); i++) {
            JSONObject jsonObject = data.getJSONObject(i);
            String TABLECOLUMN_CODE = jsonObject.getString("TABLECOLUMN_CODE");
            String TABLECOLUMN_NAME = jsonObject.getString("TABLECOLUMN_NAME");
            //列名称 校验
            if(StringUtil.isEmpty(TABLECOLUMN_NAME)){
                result = MessageUtils.getMessage("table.column.name.canNotEmpty");
                break;
            }
            if(TABLECOLUMN_NAME.length()>40){
                result = MessageUtils.getMessage("table.column.name.lengthTooLong");
                break;
            }
            Pattern pattern= Pattern.compile("[\\\\*?？：“”<>|/]");
            if(pattern.matcher(TABLECOLUMN_NAME).find()){
                result = MessageUtils.getMessage("table.column.name.include.IllegalCharacter");
                break;
            }

            //列编码 校验
            String JE_CORE_TABLECOLUMN_ID = jsonObject.getString("JE_CORE_TABLECOLUMN_ID");
            if (TABLECOLUMN_CODE.length()>40) {
                result = MessageUtils.getMessage("table.column.code.lengthTooLong",TABLECOLUMN_CODE);
                break;
            }
            if("1".equals(RESOURCETABLE_IMPORT) || TableType.VIEWTABLE.equals(RESOURCETABLE_TYPE)){
                //导入的表和视图不校验大小写
                boolean matches = TABLECOLUMN_CODE.matches("^[a-zA-Z]{1}[a-zA-Z_0-9]{0,40}$");
                if(!matches){
                    result = MessageUtils.getMessage("table.column.code.format1.error");
                    break;
                }
            }else{
                //在平台建的表，字段必须是大写
                //规则是大写
                boolean matches = TABLECOLUMN_CODE.matches("^[A-Z]{1}[A-Z_0-9]{0,40}$");
                if(!matches){
                    result = MessageUtils.getMessage("table.column.code.format2.error");
                    break;
                }
            }

            String TABLECOLUMN_RESOURCETABLE_ID = jsonObject.getString("TABLECOLUMN_RESOURCETABLE_ID");
            ConditionsWrapper select = ConditionsWrapper.builder().
                    table("JE_CORE_TABLECOLUMN")
                    .eq("TABLECOLUMN_RESOURCETABLE_ID", TABLECOLUMN_RESOURCETABLE_ID)
                    .eq("TABLECOLUMN_CODE", TABLECOLUMN_CODE).ne("JE_CORE_TABLECOLUMN_ID", JE_CORE_TABLECOLUMN_ID);
            if (commonCheckService.checkRepeat(select)) {
                result = MessageUtils.getMessage("table.column.code.repeat");
                break;
            }
            boolean success = codes.add(TABLECOLUMN_CODE);
            if (!success) {
                result = MessageUtils.getMessage("table.column.code.repeat");
                break;
            }
            //备注校验
            String TABLECOLUMN_REMARK = jsonObject.getString("TABLECOLUMN_REMARK");
            if(StringUtil.isNotEmpty(TABLECOLUMN_REMARK)){
                if(TABLECOLUMN_REMARK.length()>255){
                    result = MessageUtils.getMessage("table.column.remark.lengthTooLong");
                    break;
                }

                if(pattern.matcher(TABLECOLUMN_REMARK).find()){
                    result = MessageUtils.getMessage("table.column.remark.include.IllegalCharacter");
                    break;
                }
            }
        }

        return result;
    }

    @Override
    public InputStream exportColumns(String title,String type,  String tableCodes) {
        List<DynaBean> tables =  metaService.select("JE_CORE_RESOURCETABLE",
                ConditionsWrapper.builder().in("RESOURCETABLE_TABLECODE",Arrays.asList(tableCodes.split(","))));
        //封装字典数据
        XSSFWorkbook wb = new XSSFWorkbook();
        XSSFSheet sheet = wb.createSheet("第一页");
        //HSSFPalette customPalette = wb.getCustomPalette();
        /**--------------------声明样式----------------------------*/
        //设置标题样式
        XSSFCellStyle titleStyle=wb.createCellStyle();
        XSSFFont titleFont=wb.createFont();
        //customPalette.setColorAtIndex(HSSFColor.HSSFColorPredefined.LIGHT_GREEN.getIndex(), (byte)219, (byte)238, (byte)243);
        titleFont.setFontName("宋体");
        titleFont.setFontHeightInPoints((short) 18);//字号
        titleStyle.setAlignment(HorizontalAlignment.CENTER);
        titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        titleStyle.setFillForegroundColor(HSSFColor.HSSFColorPredefined.LIGHT_GREEN.getIndex());
        titleStyle.setFont(titleFont);
        //设置列名样式
        XSSFCellStyle columnStyle=wb.createCellStyle();
        XSSFFont columnFont=wb.createFont();
        columnFont.setFontName("宋体");
        columnFont.setFontHeightInPoints((short) 12);//字号

        columnStyle.setAlignment(HorizontalAlignment.CENTER);
        columnStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        columnStyle.setFont(columnFont);
        columnStyle.setWrapText(true);
        columnStyle.setBorderTop(BorderStyle.THIN);
        columnStyle.setBorderLeft(BorderStyle.THIN);
        columnStyle.setBorderRight(BorderStyle.THIN);
        columnStyle.setBorderBottom(BorderStyle.THIN);
        //设置数据样式
        XSSFCellStyle dataStyle=wb.createCellStyle();
        XSSFFont dataFont=wb.createFont();
        dataFont.setFontName("宋体");
        dataFont.setFontHeightInPoints((short) 10);//字号
        dataStyle.setFont(dataFont);
        dataStyle.setBorderTop(BorderStyle.THIN);
        dataStyle.setBorderLeft(BorderStyle.THIN);
        dataStyle.setBorderRight(BorderStyle.THIN);
        dataStyle.setBorderBottom(BorderStyle.THIN);
        //共有多少列
        String[] fields=new String[]{"序号","中文名","英文名","数据类型","长度","精度","主键","外键","是否为空","备注"};
        //设置标题
        XSSFRow titleRow=sheet.createRow(0);
        titleRow.setHeightInPoints(30);
        XSSFCell titleCell=titleRow.createCell(0);
        sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, fields.length-1));
        titleCell.setCellStyle(titleStyle);
        titleCell.setCellValue(title);

        int startRow=2;
        XSSFRow nowRow=null;
        XSSFCell nowCell=null;
        CellRangeAddress nowRangeAddress=null;
        sheet.setColumnWidth(1, 4800);
        sheet.setColumnWidth(2, 4800);
        for(DynaBean table:tables){
            //1.生成表信息
            nowRow=sheet.createRow(startRow);
            nowCell=nowRow.createCell(0);
            nowCell.setCellValue("表名");
            nowCell.setCellStyle(dataStyle);
            nowCell=nowRow.createCell(1);
            sheet.addMergedRegion(new CellRangeAddress(startRow, startRow, 1, fields.length-1));
            nowCell.setCellStyle(dataStyle);
            nowCell.setCellValue(table.getStr("RESOURCETABLE_TABLECODE"));
            startRow++;
            nowRow=sheet.createRow(startRow);
            nowCell=nowRow.createCell(0);
            nowCell.setCellValue("中文名");
            nowCell.setCellStyle(dataStyle);
            nowCell=nowRow.createCell(1);
            sheet.addMergedRegion(new CellRangeAddress(startRow, startRow, 1, fields.length-1));
            nowCell.setCellStyle(dataStyle);
            nowCell.setCellValue(table.getStr("RESOURCETABLE_TABLENAME"));

            startRow++;
            nowRow=sheet.createRow(startRow);
            for(int i=0;i<fields.length;i++){
                nowCell=nowRow.createCell(i);
                nowCell.setCellValue(fields[i]);
                nowCell.setCellStyle(columnStyle);
            }
            List<DynaBean> columns=metaService.select("JE_CORE_TABLECOLUMN",ConditionsWrapper.builder().eq("TABLECOLUMN_RESOURCETABLE_ID",table.getStr("JE_CORE_RESOURCETABLE_ID")).orderByAsc("TABLECOLUMN_CLASSIFY,SY_ORDERINDEX"));
            List<DynaBean> keys=metaService.select("JE_CORE_TABLEKEY",ConditionsWrapper.builder().eq("TABLEKEY_TYPE","Foreign").eq("TABLEKEY_RESOURCETABLE_ID",table.getStr("JE_CORE_RESOURCETABLE_ID")));

            Set<String> keyCodes=new HashSet<String>();
            for(DynaBean key:keys){
                keyCodes.add(key.getStr("TABLEKEY_COLUMNCODE"));
            }
            for(int i=0;i<columns.size();i++){
                DynaBean column=columns.get(i);
                String code=column.getStr("TABLECOLUMN_CODE");
                String columnType=column.getStr("TABLECOLUMN_TYPE");
                String columnLenth="";
                String columnJd="";
                String pkFlag="否";
                String foreign="否";
                String isNull="是";
//				String resColumnType="varchar2";
                if("VARCHAR30".equals(columnType)){
                    columnLenth="30";
                }else if("VARCHAR50".equals(columnType)){
                    columnLenth="50";
                }else if("VARCHAR100".equals(columnType)){
                    columnLenth="100";
                }else if("VARCHAR255".equals(columnType)){
                    columnLenth="255";
                }else if("VARCHAR1000".equals(columnType)){
                    columnLenth="1000";
                }else if("VARCHAR4000".equals(columnType)){
                    columnLenth="4000";
                }else if("VARCHAR".equals(columnType)){
                    columnLenth=column.getStr("TABLECOLUMN_LENGTH");
                }else if("ID".equals(columnType)){
                    columnLenth="50";
                    pkFlag="是";
                    isNull="否";
                }else if("FOREIGNKEY".equals(columnType)){
                    columnLenth="50";
                }else if("DATE".equals(columnType)){
                    columnLenth="12";
                }else if("DATETIME".equals(columnType)){
                    columnLenth="20";
                }else if("YESORNO".equals(columnType)){
                    columnLenth="4";
                }else{
                    columnLenth="";
                }
                columnType="varchar2";
                if(JEDatabase.getCurrentDatabase().equalsIgnoreCase(ConstantVars.STR_SQLSERVER)){
                    columnType="varchar";
                }else if(JEDatabase.getCurrentDatabase().equalsIgnoreCase(ConstantVars.STR_MYSQL)|| JEDatabase.getCurrentDatabase().equalsIgnoreCase(ConstantVars.STR_TIDB)){
                    columnType="varchar";
                }
                if("NUMBER".equals(column.getStr("TABLECOLUMN_TYPE"))){
                    columnType="number";
                    columnLenth= StringUtil.getDefaultValue(column.getStr("TABLECOLUMN_LENGTH"),"20");
                    if(JEDatabase.getCurrentDatabase().equalsIgnoreCase(ConstantVars.STR_SQLSERVER)){
                        columnType="int";
                        columnLenth="";
                    }else if(JEDatabase.getCurrentDatabase().equalsIgnoreCase(ConstantVars.STR_MYSQL)|| JEDatabase.getCurrentDatabase().equalsIgnoreCase(ConstantVars.STR_TIDB)){
                        columnType="int";
                        columnLenth="";
                    }
                }else if("FLOAT".equals(column.getStr("TABLECOLUMN_TYPE"))){
                    columnType="number";
                    columnLenth="20";
                    columnJd= StringUtil.getDefaultValue(column.getStr("TABLECOLUMN_LENGTH"),"2");
                    if(JEDatabase.getCurrentDatabase().equalsIgnoreCase(ConstantVars.STR_SQLSERVER)){
                        columnType="NUMERIC";
                    }else if(JEDatabase.getCurrentDatabase().equalsIgnoreCase(ConstantVars.STR_MYSQL)|| JEDatabase.getCurrentDatabase().equalsIgnoreCase(ConstantVars.STR_TIDB)){
                        columnType="DECIMAL";
                    }
                }else if("FLOAT2".equals(column.getStr("TABLECOLUMN_TYPE"))){
                    columnType="number";
                    columnLenth="20";
                    columnJd="2";
                    if(JEDatabase.getCurrentDatabase().equalsIgnoreCase(ConstantVars.STR_SQLSERVER)){
                        columnType="numeric";
                        columnLenth="20";
                    }else if(JEDatabase.getCurrentDatabase().equalsIgnoreCase(ConstantVars.STR_MYSQL)|| JEDatabase.getCurrentDatabase().equalsIgnoreCase(ConstantVars.STR_TIDB)){
                        columnType="decimal";
                        columnLenth="20";
                    }
                }else if("CLOB".equals(column.getStr("TABLECOLUMN_TYPE")) || "BIGCLOB".equals(column.getStr("TABLECOLUMN_TYPE"))){
                    columnType="CLOB";
                    columnLenth="";
                    columnJd="";
                    if(JEDatabase.getCurrentDatabase().equalsIgnoreCase(ConstantVars.STR_SQLSERVER)
                            || JEDatabase.getCurrentDatabase().equalsIgnoreCase(ConstantVars.STR_MYSQL)|| JEDatabase.getCurrentDatabase().equalsIgnoreCase(ConstantVars.STR_TIDB)){
                        columnType="text";
                        columnLenth="";
                    }else if(JEDatabase.getCurrentDatabase().equalsIgnoreCase(ConstantVars.STR_DM)){
                        columnType="LONGVARCHAR";
                        columnLenth="";
                    }
                }
                if(keyCodes.contains(code)){
                    foreign="是";
                }
                startRow++;
                nowRow=sheet.createRow(startRow);
                //序号
                nowCell=nowRow.createCell(0);
                nowCell.setCellValue(i+1);
                nowCell.setCellStyle(dataStyle);
                //中文名
                nowCell=nowRow.createCell(1);
                nowCell.setCellValue(column.getStr("TABLECOLUMN_NAME"));
                nowCell.setCellStyle(dataStyle);
                //英文名
                nowCell=nowRow.createCell(2);
                nowCell.setCellValue(column.getStr("TABLECOLUMN_CODE"));
                nowCell.setCellStyle(dataStyle);
                //数据类型
                nowCell=nowRow.createCell(3);
                nowCell.setCellValue(columnType);
                nowCell.setCellStyle(dataStyle);
                //长度
                nowCell=nowRow.createCell(4);
                nowCell.setCellValue(columnLenth);
                nowCell.setCellStyle(dataStyle);
                //经度
                nowCell=nowRow.createCell(5);
                nowCell.setCellValue(columnJd);
                nowCell.setCellStyle(dataStyle);
                //主键
                nowCell=nowRow.createCell(6);
                nowCell.setCellValue(pkFlag);
                nowCell.setCellStyle(dataStyle);
                //外键
                nowCell=nowRow.createCell(7);
                nowCell.setCellValue(foreign);
                nowCell.setCellStyle(dataStyle);
                //备注
                nowCell=nowRow.createCell(8);
                nowCell.setCellValue(isNull);
                nowCell.setCellStyle(dataStyle);
                //备注
                nowCell=nowRow.createCell(9);
                nowCell.setCellValue(column.getStr("TABLECOLUMN_REMARK",""));
                nowCell.setCellStyle(dataStyle);
            }
            startRow++;
        }
        try {

            //初始化输出流
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            //将Excel内容写入输出流
            wb.write(outputStream);
            //输出转输入
            ByteArrayInputStream inputStream = IoUtil.toStream(outputStream.toByteArray());
            //关闭ExcelWriter outputStream
            IoUtil.close(wb);
            IoUtil.close(outputStream);
            return inputStream;
        } catch (IOException e) {
            throw new PlatformException("表结构导出失败！", PlatformExceptionEnum.JE_CORE_EXCEL_EXP_ERROR, e);
        }
    }

    @Override
    public String checkColumnBelongtoView(String resourceId, String columnCode) {
        DynaBean resourceTable = metaService.selectOneByPk("JE_CORE_RESOURCETABLE", resourceId);
        List<Map<String, Object>> viewColumns = metaService.selectSql("SELECT  TABLECOLUMN_TABLECODE,TABLECOLUMN_VIEWCONFIG FROM JE_CORE_TABLECOLUMN WHERE TABLECOLUMN_RESOURCETABLE_ID IN (SELECT JE_CORE_RESOURCETABLE_ID FROM JE_CORE_RESOURCETABLE WHERE RESOURCETABLE_TABLESINFO LIKE '%" + resourceId + "%')");
        /**
         * 校验是否用于创建视图
         */
        String tableAnColumn1 = resourceTable.getStr("RESOURCETABLE_TABLECODE") + "." + columnCode;
        for (Map<String, Object> map : viewColumns) {
            String viewConfig = map.get("TABLECOLUMN_VIEWCONFIG") == null ? "" : map.get("TABLECOLUMN_VIEWCONFIG").toString();
            String tableCode = map.get("TABLECOLUMN_TABLECODE") == null ? "" : map.get("TABLECOLUMN_TABLECODE").toString();
            if (StringUtil.isNotEmpty(viewConfig)) {
                JSONObject jsonObject = JSONObject.parseObject(viewConfig);
                String tableAnColumn2 = jsonObject.getString("value");
                if (tableAnColumn1.equals(tableAnColumn2)) {
                    return MessageUtils.getMessage("table.column.useFor.view", columnCode, tableCode);
                }
            }
        }
        return null;
    }

    /**
     * 产品相关字段
     */
    private boolean initSecretColumn(HttpServletRequest request) {
        String resourceId = getStringParameter(request, "JE_CORE_RESOURCETABLE_ID");
        DynaBean table = metaService.selectOneByPk("JE_CORE_RESOURCETABLE", resourceId);
        if (table != null) {
            metaTableColumnService.initSecretColumns(table);
        }
        return true;
    }

    /**
     * 产品相关字段
     */
    private boolean initProductColumn(HttpServletRequest request) {
        String resourceId = getStringParameter(request, "JE_CORE_RESOURCETABLE_ID");
        DynaBean table = metaService.selectOneByPk("JE_CORE_RESOURCETABLE", resourceId);
        if (table != null) {
            metaTableColumnService.initProductColumns(table);
        }
        return true;
    }

    /**
     * 拓展相关字段
     */
    private boolean initExtendColumn(HttpServletRequest request) throws APIWarnException {
        String resourceId = getStringParameter(request, "JE_CORE_RESOURCETABLE_ID");
        DynaBean table = metaService.selectOneByPk("JE_CORE_RESOURCETABLE", resourceId);
        if (table != null) {
            return metaTableColumnService.initExtendColumns(table);
        }
        return true;
    }

    /**
     * saas相关字段
     */
    private boolean initSaasColumn(HttpServletRequest request) {
        String resourceId = getStringParameter(request, "JE_CORE_RESOURCETABLE_ID");
        DynaBean table = metaService.selectOneByPk("JE_CORE_RESOURCETABLE", resourceId);
        if (table != null) {
            metaTableColumnService.initSaasColumns(table);
        }
        return true;
    }

    /**
     * 流程相关字段
     */
    private boolean initWfBaseColumn(HttpServletRequest request) throws APIWarnException {
        String resourceId = getStringParameter(request, "JE_CORE_RESOURCETABLE_ID");
        DynaBean table = metaService.selectOneByPk("JE_CORE_RESOURCETABLE", resourceId);
        if (table != null) {
            return metaTableColumnService.initWfBaseColumns(table);
        }
        return true;
    }

    /**
     * 流程相关字段
     */
    private boolean initWfExtendColumn(HttpServletRequest request) throws APIWarnException {
        String resourceId = getStringParameter(request, "JE_CORE_RESOURCETABLE_ID");
        DynaBean table = metaService.selectOneByPk("JE_CORE_RESOURCETABLE", resourceId);
        if (table != null) {
            return metaTableColumnService.initProcessExtendColumns(table);
        }
        return true;
    }

    /**
     * 修改相关字段
     */
    private boolean generateUpdateInfo(HttpServletRequest request) throws APIWarnException {
        String resourceId = getStringParameter(request, "JE_CORE_RESOURCETABLE_ID");
        if (StringUtil.isNotEmpty(resourceId)) {
            DynaBean table = metaService.selectOneByPk("JE_CORE_RESOURCETABLE", resourceId);
            return metaTableColumnService.initUpdateColumns(table);
        } else {
            return false;
        }
    }

    /**
     * 新增相关字段
     */
    private boolean generateCreateInfo(HttpServletRequest request) throws APIWarnException {
        String resourceId = getStringParameter(request, "JE_CORE_RESOURCETABLE_ID");
        if (StringUtil.isNotEmpty(resourceId)) {
            DynaBean table = metaService.selectOneByPk("JE_CORE_RESOURCETABLE", resourceId);
//            Long count = metaService.countBySql(ConditionsWrapper.builder()
//                    .table("JE_CORE_TABLECOLUMN")
//                    .eq("TABLECOLUMN_CODE", "SY_CREATETIME")
//                    .eq("TABLECOLUMN_RESOURCETABLE_ID", resourceId));
//            if (count > 0) {
//                return BaseRespResult.errorResult("该表已经存在 SY_CREATETIME ，请删除后重新生成!");

            return metaTableColumnService.initCreateColumns(table);
        } else {
            return false;
        }

    }


    /**
     * 辅助函数初始化列(传址操作)
     *
     * @param tableColumn
     * @param code
     * @param name
     * @param orderIndex
     */
    private void buildColumn(DynaBean tableColumn, String code, String name, int orderIndex) {
        tableColumn.set("TABLECOLUMN_CODE", code);
        tableColumn.set("TABLECOLUMN_NAME", name);
        tableColumn.set("TABLECOLUMN_TREETYPE", "NORMAL");
        if ("SY_ORDERINDEX".equals(code)) {
            tableColumn.set("TABLECOLUMN_TYPE", "NUMBER");
            tableColumn.set("TABLECOLUMN_LENGTH", "20");
        } else {
            tableColumn.set("TABLECOLUMN_TYPE", "VARCHAR255");
        }
        tableColumn.set("SY_ORDERINDEX", orderIndex);
        tableColumn.set("TABLECOLUMN_ISNULL", "1");
        tableColumn.set("TABLECOLUMN_CLASSIFY", "SYS");
    }

    /**
     * 获取删除表字段，对应视图中存在此字段的ID列表
     * 此逻辑是判断资源表视图列中字段值TABLECOLUMN_VIEWCONFIG
     *
     * @param tableCode   资源表编码
     * @param columns     需要删除的列
     * @param viewColumns 视图中存在的列
     * @return
     */
    private List<DynaBean> acquireEqualColumns(String tableCode, List<DynaBean> columns, List<DynaBean> viewColumns) {
        List<DynaBean> columnIds = Lists.newArrayList();
        for (DynaBean eachDelColumnBean : columns) {
            for (DynaBean eachViewColumnBean : viewColumns) {
                String viewColumnConfigStr = eachViewColumnBean.getStr("TABLECOLUMN_VIEWCONFIG");
                if (Strings.isNullOrEmpty(viewColumnConfigStr)) {
                    continue;
                }
                JSONObject viewColumnObj = JSON.parseObject(viewColumnConfigStr);
                if (tableCode.equals(viewColumnObj.getString("table"))
                        && viewColumnObj.getString("code").equals(eachDelColumnBean.getStr("TABLECOLUMN_CODE"))) {
                    columnIds.add(eachViewColumnBean);
                }
            }
        }
        return columnIds;
    }


}
